diff --git a/.asf.yaml b/.asf.yaml index 6c78530425..bb5d874a3f 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -34,14 +34,15 @@ github: protected_branches: master: required_status_checks: - # strict means "Require branches to be up-to-date before merging". (TODO: turnoff when branch is stable) - strict: true + # strict means "Require PR to be up-to-date before merging". (enable when branch unstable) + strict: false # contexts are the names of checks that must pass (now only enable the basic check) contexts: - Analyze (java) - CodeQL - check-license - - build (memory, 11) + - build-server (memory, 11) + - build-commons (11) required_pull_request_reviews: dismiss_stale_reviews: true require_code_owner_reviews: false diff --git a/.gitattributes b/.gitattributes index ca5e57db70..85f64d198b 100755 --- a/.gitattributes +++ b/.gitattributes @@ -12,4 +12,5 @@ hugegraph-store/hg-store-dist/src/assembly/static/bin/libjemalloc_aarch64.so exp .github/ export-ignore .idea/ export-ignore install-dist/scripts/ export-ignore +hugegraph-commons/hugegraph-dist/ export-ignore docker/ export-ignore diff --git a/.github/workflows/check-dependencies.yml b/.github/workflows/check-dependencies.yml index 6e3c572889..68f8c0e0c9 100644 --- a/.github/workflows/check-dependencies.yml +++ b/.github/workflows/check-dependencies.yml @@ -32,7 +32,7 @@ jobs: - name: mvn install run: | - mvn install -DskipTests=true -ntp + mvn install -Dmaven.test.skip=true -ntp - name: generate current dependencies run: | bash $SCRIPT_DEPENDENCY/regenerate_known_dependencies.sh current-dependencies.txt diff --git a/.github/workflows/cluster-test-ci.yml b/.github/workflows/cluster-test-ci.yml new file mode 100644 index 0000000000..7abebc7224 --- /dev/null +++ b/.github/workflows/cluster-test-ci.yml @@ -0,0 +1,52 @@ +name: "Cluster Test CI" + +on: + push: + branches: + - master + - 'release-*' + - 'test-*' + pull_request: + +jobs: + cluster-test: + runs-on: ubuntu-latest + env: + USE_STAGE: 'true' # Whether to include the stage repository. + + 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: Run simple cluster test + run: | + mvn test -pl hugegraph-cluster-test/hugegraph-clustertest-test -am -P simple-cluster-test -DskipCommonsTests=true + + - name: Run multi cluster test + run: | + mvn test -pl hugegraph-cluster-test/hugegraph-clustertest-test -am -P multi-cluster-test -DskipCommonsTests=true diff --git a/.github/workflows/commons-ci.yml b/.github/workflows/commons-ci.yml new file mode 100644 index 0000000000..7b781dd4a5 --- /dev/null +++ b/.github/workflows/commons-ci.yml @@ -0,0 +1,64 @@ +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 -DskipCommonsTests=false + + - name: Run rpc test + run: | + mvn test -pl hugegraph-commons/hugegraph-rpc -Dtest=UnitTestSuite -DskipCommonsTests=false + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3.0.0 + with: + file: target/jacoco.xml diff --git a/.github/workflows/pd-store-ci.yml b/.github/workflows/pd-store-ci.yml index c0f4825251..44d4456920 100644 --- a/.github/workflows/pd-store-ci.yml +++ b/.github/workflows/pd-store-ci.yml @@ -1,4 +1,4 @@ -name: "Graph PD & Store & Hstore CI" +name: "HugeGraph-PD & Store & Hstore CI" on: push: @@ -14,7 +14,8 @@ jobs: runs-on: ubuntu-latest env: # TODO: avoid duplicated env setup in pd & store - USE_STAGE: 'false' # Whether to include the stage repository. + # 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 @@ -46,11 +47,11 @@ jobs: - name: Run common test run: | - mvn test -pl hugegraph-pd/hg-pd-test -am -P pd-common-test + 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 + 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. @@ -64,11 +65,11 @@ jobs: - name: Run client test run: | - mvn test -pl hugegraph-pd/hg-pd-test -am -P pd-client-test + 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 + 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 @@ -79,7 +80,7 @@ jobs: # TODO: avoid duplicated env setup runs-on: ubuntu-latest env: - USE_STAGE: 'false' # Whether to include the stage repository. + 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 @@ -120,27 +121,27 @@ jobs: - name: Run common test run: | - mvn test -pl hugegraph-store/hg-store-test -am -P store-common-test + 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 + 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 + 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 + 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 + 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 + 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 diff --git a/.github/workflows/server-ci.yml b/.github/workflows/server-ci.yml index bbf8a5eab6..d640124ff1 100644 --- a/.github/workflows/server-ci.yml +++ b/.github/workflows/server-ci.yml @@ -1,4 +1,4 @@ -name: "Graph Server CI" +name: "HugeGraph-Server CI" on: push: @@ -9,11 +9,12 @@ on: pull_request: jobs: - build: + build-server: # TODO: we need test & replace it to ubuntu-24.04 or ubuntu-latest runs-on: ubuntu-20.04 env: - USE_STAGE: 'false' # Whether to include the stage repository. + # 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 BACKEND: ${{ matrix.BACKEND }} diff --git a/BUILDING.md b/BUILDING.md index b7342e68d6..d4c807c748 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -6,7 +6,7 @@ Required: * Java 11 * Maven 3.5+ -To build without executing tests: `mvn clean package -DskipTests` +To build without executing tests: `mvn clean package -Dmaven.test.skip=true` ## Building in IDEA diff --git a/hugegraph-cluster-test/hugegraph-clustertest-dist/pom.xml b/hugegraph-cluster-test/hugegraph-clustertest-dist/pom.xml new file mode 100644 index 0000000000..20e3efc599 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-dist/pom.xml @@ -0,0 +1,78 @@ + + + + + 4.0.0 + + org.apache.hugegraph + hugegraph-cluster-test + ${revision} + ../pom.xml + + + hugegraph-clustertest-dist + + + ${project.parent.basedir} + bash + ${project.basedir}/src/assembly + ${assembly.dir}/descriptor + ${assembly.dir}/static + hg-ct + + + + + + maven-assembly-plugin + 2.4 + + + assembly-hugegraph-ct + package + + single + + + false + false + ${dist.dir} + + + ${assembly.descriptor.dir}/assembly.xml + + + ${final.name} + + + + + + + + + + org.apache.hugegraph + hugegraph-clustertest-minicluster + ${revision} + + + + diff --git a/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/descriptor/assembly.xml b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/descriptor/assembly.xml new file mode 100644 index 0000000000..3db49f4266 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/descriptor/assembly.xml @@ -0,0 +1,50 @@ + + + + distribution + false + + + dir + + + + + ${assembly.static.dir} + / + + **/* + + + + + + + + + /lib + false + runtime + false + + org.apache.hugegraph:${executable.jar.name}:jar:* + + + + + diff --git a/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/hugegraph.properties.template b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/hugegraph.properties.template new file mode 100644 index 0000000000..8eaf0adffb --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/hugegraph.properties.template @@ -0,0 +1,126 @@ +# +# 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. +# + +# gremlin entrance to create graph +# auth config: org.apache.hugegraph.auth.HugeFactoryAuthProxy +gremlin.graph=org.apache.hugegraph.HugeFactory + +# cache config +#schema.cache_capacity=100000 +# vertex-cache default is 1000w, 10min expired +vertex.cache_type=l2 +#vertex.cache_capacity=10000000 +#vertex.cache_expire=600 +# edge-cache default is 100w, 10min expired +edge.cache_type=l2 +#edge.cache_capacity=1000000 +#edge.cache_expire=600 + + +# schema illegal name template +#schema.illegal_name_regex=\s+|~.* + +#vertex.default_label=vertex + +backend=hstore +serializer=binary + +store=hugegraph + +# pd config +pd.peers=$PD_PEERS_LIST$ + +# task config +task.scheduler_type=local +task.schedule_period=10 +task.retry=0 +task.wait_timeout=10 + +# raft config +raft.mode=false +raft.path=./raft-log +raft.safe_read=true +raft.use_replicator_pipeline=true +raft.election_timeout=10000 +raft.snapshot_interval=3600 +raft.backend_threads=48 +raft.read_index_threads=8 +raft.snapshot_threads=4 +raft.snapshot_parallel_compress=false +raft.snapshot_compress_threads=4 +raft.snapshot_decompress_threads=4 +raft.read_strategy=ReadOnlyLeaseBased +raft.queue_size=16384 +raft.queue_publish_timeout=60 +raft.apply_batch=1 +raft.rpc_threads=80 +raft.rpc_connect_timeout=5000 +raft.rpc_timeout=60 +raft.install_snapshot_rpc_timeout=36000 + +# search config +search.text_analyzer=jieba +search.text_analyzer_mode=INDEX + +# rocksdb backend config +#rocksdb.data_path=/path/to/disk +#rocksdb.wal_path=/path/to/disk + + +# cassandra backend config +cassandra.host=localhost +cassandra.port=9042 +cassandra.username= +cassandra.password= +#cassandra.connect_timeout=5 +#cassandra.read_timeout=20 +#cassandra.keyspace.strategy=SimpleStrategy +#cassandra.keyspace.replication=3 + +# hbase backend config +#hbase.hosts=localhost +#hbase.port=2181 +#hbase.znode_parent=/hbase +#hbase.threads_max=64 +# IMPORTANT: recommend to modify the HBase partition number +# by the actual/env data amount & RS amount before init store +# It will influence the load speed a lot +#hbase.enable_partition=true +#hbase.vertex_partitions=10 +#hbase.edge_partitions=30 + +# mysql backend config +#jdbc.driver=com.mysql.jdbc.Driver +#jdbc.url=jdbc:mysql://127.0.0.1:3306 +#jdbc.username=root +#jdbc.password= +#jdbc.reconnect_max_times=3 +#jdbc.reconnect_interval=3 +#jdbc.ssl_mode=false + +# postgresql & cockroachdb backend config +#jdbc.driver=org.postgresql.Driver +#jdbc.url=jdbc:postgresql://localhost:5432/ +#jdbc.username=postgres +#jdbc.password= +#jdbc.postgresql.connect_database=template1 + +# palo backend config +#palo.host=127.0.0.1 +#palo.poll_interval=10 +#palo.temp_dir=./palo-data +#palo.file_limit_size=32 diff --git a/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/pd-application.yml.template b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/pd-application.yml.template new file mode 100644 index 0000000000..87229aabcf --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/pd-application.yml.template @@ -0,0 +1,80 @@ +# +# 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: $GRPC_PORT$ + # The service address of grpc needs to be changed to the actual local IPv4 address when deploying. + host: 127.0.0.1 + +server: + # REST service port number + port : $REST_PORT$ + +pd: + # Storage path + data-path: ./pd_data + # The check cycle of automatic expansion regularly checks the number of partitions in each store and automatically balances the number of partitions + patrol-interval: 1800 + # The minimum number of surviving store nodes, less than which the entire cluster is unavailable + initial-store-count: $STORE_COUNT$ + # The initial store list, grpc IP: grpc port, the store in the list is automatically activated + initial-store-list: $STORE_GRPC_LIST$ + + +raft: + # The address of the local raft service + address: $RAFT_ADDRESS$ + # The service address of the PD cluster + peers-list: $RAFT_PEERS_LIST$ + +store: + # The time when the store went offline. After that time, the store is considered permanently unavailable, and the replica is allocated to another machine, in seconds + max-down-time: 172800 + # Specifies whether to enable store monitoring data storage + monitor_data_enabled: true + # The interval between monitoring data, minute, hour, second + # default: 1 min * 1 day = 1440 + monitor_data_interval: 1 minute + # Retention time of monitoring data is 1 day; day, month, year + monitor_data_retention: 1 day + initial-store-count: 1 + +partition: + # Default number of replicas per partition + default-shard-count: 1 + # The default maximum number of replicas per machine + # the initial number of partitions= store-max-shard-count * store-number / default-shard-count + store-max-shard-count: 12 diff --git a/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/rest-server.properties.template b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/rest-server.properties.template new file mode 100644 index 0000000000..8f4e9bf616 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/rest-server.properties.template @@ -0,0 +1,71 @@ +# +# 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. +# + +# bind url +# could use '0.0.0.0' or specified (real)IP to expose external network access +restserver.url=http://$REST_SERVER_ADDRESS$ +# gremlin server url, need to be consistent with host and port in gremlin-server.yaml +#gremlinserver.url=http://$REST_SERVER_ADDRESS$ + +graphs=./conf/graphs + +# The maximum thread ratio for batch writing, only take effect if the batch.max_write_threads is 0 +batch.max_write_ratio=80 +batch.max_write_threads=0 + +# 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= + +# for StandardAuthenticator mode +#auth.graph_store=hugegraph +# auth client config +#auth.remote_url=127.0.0.1:8899,127.0.0.1:8898,127.0.0.1:8897 + +# for ConfigAuthenticator mode +#auth.admin_token= +#auth.user_tokens=[] + +# rpc server configs for multi graph-servers or raft-servers +rpc.server_host=127.0.0.1 +rpc.server_port=$RPC_PORT$ +#rpc.server_timeout=30 + +# rpc client configs (like enable to keep cache consistency) +#rpc.remote_url=127.0.0.1:8091,127.0.0.1:8092,127.0.0.1:8093 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash + +# raft group initial peers +#raft.group_peers=127.0.0.1:8091,127.0.0.1:8092,127.0.0.1:8093 + +# lightweight load balancing (beta) +server.id=$SERVER_ID$ +server.role=$ROLE$ + +# slow query log +log.slow_query_threshold=1000 diff --git a/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/store-application.yml.template b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/store-application.yml.template new file mode 100644 index 0000000000..93ceb76386 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-dist/src/assembly/static/conf/store-application.yml.template @@ -0,0 +1,64 @@ +# +# 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: + # PD service address, multiple PD addresses separated by commas + address: $PD_SERVER_ADDRESS$ + +management: + metrics: + export: + prometheus: + enabled: true + endpoints: + web: + exposure: + include: "*" + +grpc: + # grpc service address + host: 127.0.0.1 + port: $GRPC_PORT$ + netty-server: + max-inbound-message-size: 1000MB +raft: + # raft cache queue size + disruptorBufferSize: 1024 + address: $RAFT_ADDRESS$ + max-log-file-size: 600000000000 + # Snapshot generation interval, in seconds + snapshotInterval: 1800 +server: + # rest service address + port: $REST_PORT$ + +app: + # Storage path, support multiple paths, separated by commas + data-path: ./storage + #raft-path: ./storage + +spring: + application: + name: store-node-grpc-server + profiles: + active: default + include: pd + +logging: + config: 'file:./conf/log4j2.xml' + level: + root: info diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/pom.xml b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/pom.xml new file mode 100644 index 0000000000..8feb6181f2 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/pom.xml @@ -0,0 +1,66 @@ + + + + + 4.0.0 + hugegraph-clustertest-minicluster + + + org.apache.hugegraph + hugegraph-cluster-test + ${revision} + + + + + 11 + 11 + UTF-8 + 2.17.0 + + + + + org.apache.commons + commons-lang3 + 3.13.0 + compile + + + commons-io + commons-io + 2.12.0 + compile + + + org.slf4j + slf4j-api + 2.0.9 + compile + + + org.projectlombok + lombok + 1.18.24 + compile + + + + diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/ClusterConstant.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/ClusterConstant.java new file mode 100644 index 0000000000..9120c0cf92 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/ClusterConstant.java @@ -0,0 +1,135 @@ +/* + * 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.ct.base; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; + +import org.apache.commons.lang3.SystemUtils; + +public class ClusterConstant { + + public static final String LOG = "logs"; + public static final String PROJECT_DIR = getProjectDir(); + public static final String LIB_DIR = "lib"; + public static final String EXT_DIR = "ext"; + public static final String PLUGINS_DIR = "plugins"; + public static final String BIN_DIR = "bin"; + public static final String CONF_DIR = "conf"; + public static final String PD_PACKAGE_PREFIX = "apache-hugegraph-pd-incubating"; + public static final String PD_JAR_PREFIX = "hg-pd-service"; + public static final String STORE_PACKAGE_PREFIX = "apache-hugegraph-store-incubating"; + public static final String STORE_JAR_PREFIX = "hg-store-node"; + public static final String SERVER_PACKAGE_PREFIX = "apache-hugegraph-server-incubating"; + public static final String CT_PACKAGE_PREFIX = "apache-hugegraph-ct-incubating"; + public static final String APPLICATION_FILE = "application.yml"; + public static final String SERVER_PROPERTIES = "rest-server.properties"; + public static final String HUGEGRAPH_PROPERTIES = "graphs/hugegraph.properties"; + public static final String LOG4J_FILE = "log4j2.xml"; + public static final String PD_TEMPLATE_FILE = "pd-application.yml.template"; + public static final String STORE_TEMPLATE_FILE = "store-application.yml.template"; + public static final String SERVER_TEMPLATE_FILE = "rest-server.properties.template"; + public static final String GRAPH_TEMPLATE_FILE = "hugegraph.properties.template"; + public static final String GREMLIN_DRIVER_SETTING_FILE = "gremlin-driver-settings.yaml"; + public static final String GREMLIN_SERVER_FILE = "gremlin-server.yaml"; + public static final String REMOTE_SETTING_FILE = "remote.yaml"; + public static final String REMOTE_OBJECTS_SETTING_FILE = "remote-objects.yaml"; + public static final String EMPTY_SAMPLE_GROOVY_FILE = "scripts/empty-sample.groovy"; + public static final String EXAMPLE_GROOVY_FILE = "scripts/example.groovy"; + public static final String LOCALHOST = "127.0.0.1"; + + public static final String JAVA_CMD = + System.getProperty("java.home") + File.separator + BIN_DIR + File.separator + + (SystemUtils.IS_OS_WINDOWS ? "java.exe" : "java"); + public static final String PD_DIST_PATH = + PROJECT_DIR + File.separator + "hugegraph-pd" + File.separator; + public static final String PD_LIB_PATH = + getFileInDir(PD_DIST_PATH, PD_PACKAGE_PREFIX) + File.separator + LIB_DIR + + File.separator; + public static final String PD_TEMPLATE_PATH = + getFileInDir(PD_DIST_PATH, PD_PACKAGE_PREFIX) + File.separator + CONF_DIR + + File.separator; + public static final String STORE_DIST_PATH = + PROJECT_DIR + File.separator + "hugegraph-store" + File.separator; + public static final String STORE_LIB_PATH = + getFileInDir(STORE_DIST_PATH, STORE_PACKAGE_PREFIX) + File.separator + LIB_DIR + + File.separator; + public static final String STORE_TEMPLATE_PATH = + getFileInDir(STORE_DIST_PATH, STORE_PACKAGE_PREFIX) + File.separator + CONF_DIR + + File.separator; + public static final String SERVER_DIST_PATH = + PROJECT_DIR + File.separator + "hugegraph-server" + File.separator; + public static final String SERVER_LIB_PATH = + getFileInDir(SERVER_DIST_PATH, SERVER_PACKAGE_PREFIX) + + File.separator; + public static final String SERVER_PACKAGE_PATH = + getFileInDir(SERVER_DIST_PATH, SERVER_PACKAGE_PREFIX) + + File.separator; + public static final String SERVER_TEMPLATE_PATH = + SERVER_PACKAGE_PATH + CONF_DIR + File.separator; + public static final String CT_DIST_PATH = + PROJECT_DIR + File.separator + "hugegraph-cluster-test" + File.separator; + public static final String CT_PACKAGE_PATH = + getFileInDir(CT_DIST_PATH, CT_PACKAGE_PREFIX) + File.separator; + public static final String CONFIG_FILE_PATH = CT_PACKAGE_PATH + CONF_DIR + File.separator; + + private ClusterConstant() { + throw new IllegalStateException("Utility class"); + } + + public static String getFileInDir(String path, String fileName) { + File dir = new File(path); + if (dir.exists() && dir.isDirectory()) { + for (File file : Objects.requireNonNull(dir.listFiles())) { + if (file.getName().startsWith(fileName) && !file.getName().endsWith(".gz")) { + return path + file.getName(); + } + } + } + return ""; + } + + public static boolean isJava11OrHigher() { + String version = System.getProperty("java.version"); + if (version.startsWith("1.")) { + version = version.substring(2, 3); + } else { + int dot = version.indexOf("."); + if (dot != -1) { + version = version.substring(0, dot); + } + } + int versionNumber = Integer.parseInt(version); + return versionNumber >= 11; + } + + public static String getProjectDir() { + String userDir = System.getProperty("user.dir"); // get current dir + Path path = Paths.get(userDir); + + if (userDir.endsWith("hugegraph-cluster-test")) { + return path.getParent().toString(); + } else if (userDir.endsWith("hugegraph-clustertest-test")) { + return path.getParent().getParent().toString(); + } + + return userDir; // Return current dir if not matched + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/EnvType.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/EnvType.java new file mode 100644 index 0000000000..56449a42b0 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/EnvType.java @@ -0,0 +1,29 @@ +/* + * 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.ct.base; + +public enum EnvType { + + SingleNode, + MultiNode; + + public static EnvType getSystemEnvType() { + String envType = System.getProperty("test_env", SingleNode.toString()); + return EnvType.valueOf(envType); + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/EnvUtil.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/EnvUtil.java new file mode 100644 index 0000000000..4d4bab3831 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/EnvUtil.java @@ -0,0 +1,67 @@ +/* + * 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.ct.base; + +import java.io.IOException; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.HashSet; +import java.util.Set; + +import org.slf4j.Logger; + +public class EnvUtil { + + private static final Logger LOG = HGTestLogger.UTIL_LOG; + private static final Set ports = new HashSet<>(); + + public static int getAvailablePort() { + try { + int port = -1; + while (port < 0 || ports.contains(port)) { + ServerSocket socket = new ServerSocket(0); + port = socket.getLocalPort(); + socket.close(); + } + ports.add(port); + return port; + } catch (IOException e) { + LOG.error("Failed to get available ports", e); + return -1; + } + } + + public static void copyFileToDestination(Path source, Path destination) { + try { + ensureParentDirectoryExists(destination); + Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException ioException) { + LOG.error("Failed to copy files to destination dir", ioException); + throw new RuntimeException(ioException); + } + } + + private static void ensureParentDirectoryExists(Path destination) throws IOException { + Path parentDir = destination.getParent(); + if (parentDir != null && Files.notExists(parentDir)) { + Files.createDirectories(parentDir); + } + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/HGTestLogger.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/HGTestLogger.java new file mode 100644 index 0000000000..ceef1e40b3 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/base/HGTestLogger.java @@ -0,0 +1,32 @@ +/* + * 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.ct.base; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HGTestLogger { + + public static Logger UTIL_LOG = LoggerFactory.getLogger(HGTestLogger.class); + public static Logger ENV_LOG = LoggerFactory.getLogger(HGTestLogger.class); + public static Logger CONFIG_LOG = LoggerFactory.getLogger(HGTestLogger.class); + public static Logger NODE_LOG = LoggerFactory.getLogger(HGTestLogger.class); +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/AbstractConfig.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/AbstractConfig.java new file mode 100644 index 0000000000..36a7240d2f --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/AbstractConfig.java @@ -0,0 +1,82 @@ +/* + * 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.ct.config; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +import org.apache.hugegraph.ct.base.HGTestLogger; +import org.slf4j.Logger; + +public abstract class AbstractConfig { + + protected static final Logger LOG = HGTestLogger.CONFIG_LOG; + protected String config; + protected Map properties = new HashMap<>(); + protected String fileName; + + protected void readTemplate(Path filePath) { + try { + this.config = new String(Files.readAllBytes(filePath)); + } catch (IOException e) { + LOG.error("failed to get file", e); + } + } + + protected void updateConfigs() { + for (Map.Entry entry : properties.entrySet()) { + String placeholder = "$" + entry.getKey() + "$"; + this.config = this.config.replace(placeholder, entry.getValue()); + } + } + + public void writeConfig(String filePath) { + updateConfigs(); + Path destPath = Paths.get(filePath + File.separator + this.fileName); + try { + if (Files.notExists(destPath.getParent())) { + Files.createDirectories(destPath.getParent()); + } + } catch (IOException e) { + LOG.error("Failed to create dir", e); + } + try (FileWriter writer = new FileWriter(String.valueOf(destPath))) { + writer.write(this.config); + } catch (IOException e) { + LOG.error("Failed to write in file", e); + } + } + + public String getProperty(String propertyName) { + return properties.get(propertyName); + } + + protected void setProperty(String propertyName, String value) { + if (properties.containsKey(propertyName)) { + properties.replace(propertyName, value); + } else { + properties.put(propertyName, value); + } + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/ClusterConfig.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/ClusterConfig.java new file mode 100644 index 0000000000..c71e4b07e1 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/ClusterConfig.java @@ -0,0 +1,130 @@ +/* + * 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.ct.config; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hugegraph.ct.base.HGTestLogger; +import org.slf4j.Logger; + +public class ClusterConfig { + + protected static final Logger LOG = HGTestLogger.CONFIG_LOG; + protected List pdConfigs; + protected List storeConfigs; + protected List serverConfigs; + protected List graphConfigs; + + protected List pdGrpcList, pdRaftList, storeGrpcList; + + public ClusterConfig(int pdCnt, int storeCnt, int serverCnt) { + pdConfigs = new ArrayList<>(); + storeConfigs = new ArrayList<>(); + serverConfigs = new ArrayList<>(); + graphConfigs = new ArrayList<>(); + pdGrpcList = new ArrayList<>(); + pdRaftList = new ArrayList<>(); + storeGrpcList = new ArrayList<>(); + + for (int i = 0; i < pdCnt; i++) { + PDConfig pdConfig = new PDConfig(); + pdConfig.setStoreCount(storeCnt); + pdConfigs.add(pdConfig); + pdGrpcList.add(pdConfig.getGrpcAddress()); + pdRaftList.add(pdConfig.getRaftAddress()); + } + + for (int i = 0; i < storeCnt; i++) { + StoreConfig storeConfig = new StoreConfig(); + storeConfig.setPDServerList(pdGrpcList); + storeConfigs.add(storeConfig); + storeGrpcList.add(storeConfig.getGrpcAddress()); + } + + for (int i = 0; i < serverCnt; i++) { + ServerConfig serverConfig = new ServerConfig(); + serverConfigs.add(serverConfig); + GraphConfig graphConfig = new GraphConfig(); + graphConfig.setPDPeersList(pdGrpcList); + graphConfigs.add(graphConfig); + } + + for (int i = 0; i < pdCnt; i++) { + PDConfig pdConfig = pdConfigs.get(i); + pdConfig.setRaftPeerList(pdRaftList); + pdConfig.setStoreGrpcList(storeGrpcList); + } + } + + public PDConfig getPDConfig(int i) { + return pdConfigs.get(i); + } + + public StoreConfig getStoreConfig(int i) { + return storeConfigs.get(i); + } + + public ServerConfig getServerConfig(int i) { + return serverConfigs.get(i); + } + + public GraphConfig getGraphConfig(int i) { + return graphConfigs.get(i); + } + + public List getPDRestAddrs() { + List addrs = new ArrayList<>(); + for (PDConfig pdConfig : pdConfigs) { + addrs.add(pdConfig.getRaftAddress()); + } + return addrs; + } + + public List getPDGrpcAddrs() { + List addrs = new ArrayList<>(); + for (PDConfig pdConfig : pdConfigs) { + addrs.add(pdConfig.getGrpcAddress()); + } + return addrs; + } + + public List getStoreRestAddrs() { + List addrs = new ArrayList<>(); + for (StoreConfig storeConfig : storeConfigs) { + addrs.add("127.0.0.1" + ":" + storeConfig.getRestPort()); + } + return addrs; + } + + public List getStoreGrpcAddrs() { + List addrs = new ArrayList<>(); + for (StoreConfig storeConfig : storeConfigs) { + addrs.add("127.0.0.1" + ":" + storeConfig.getGrpcPort()); + } + return addrs; + } + + public List getServerRestAddrs() { + List addrs = new ArrayList<>(); + for (ServerConfig serverConfig : serverConfigs) { + addrs.add("127.0.0.1" + ":" + serverConfig.getRestPort()); + } + return addrs; + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/GraphConfig.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/GraphConfig.java new file mode 100644 index 0000000000..a6b425d51f --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/GraphConfig.java @@ -0,0 +1,38 @@ +/* + * 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.ct.config; + +import static org.apache.hugegraph.ct.base.ClusterConstant.CONFIG_FILE_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.GRAPH_TEMPLATE_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.HUGEGRAPH_PROPERTIES; + +import java.nio.file.Paths; +import java.util.List; + +public class GraphConfig extends AbstractConfig { + + public GraphConfig() { + readTemplate(Paths.get(CONFIG_FILE_PATH + GRAPH_TEMPLATE_FILE)); + this.fileName = HUGEGRAPH_PROPERTIES; + } + + public void setPDPeersList(List pdPeersList) { + String pdPeers = String.join(",", pdPeersList); + setProperty("PD_PEERS_LIST", pdPeers); + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/PDConfig.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/PDConfig.java new file mode 100644 index 0000000000..d53e45d575 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/PDConfig.java @@ -0,0 +1,70 @@ +/* + * 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.ct.config; + +import static org.apache.hugegraph.ct.base.ClusterConstant.APPLICATION_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.CONFIG_FILE_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.LOCALHOST; +import static org.apache.hugegraph.ct.base.ClusterConstant.PD_TEMPLATE_FILE; +import static org.apache.hugegraph.ct.base.EnvUtil.getAvailablePort; + +import java.nio.file.Paths; +import java.util.List; + +import lombok.Getter; + +@Getter +public class PDConfig extends AbstractConfig { + + private final int raftPort; + private final int grpcPort; + private final int restPort; + + public PDConfig() { + readTemplate(Paths.get(CONFIG_FILE_PATH + PD_TEMPLATE_FILE)); + this.fileName = APPLICATION_FILE; + this.raftPort = getAvailablePort(); + this.grpcPort = getAvailablePort(); + this.restPort = getAvailablePort(); + properties.put("GRPC_PORT", String.valueOf(this.grpcPort)); + properties.put("REST_PORT", String.valueOf(this.restPort)); + properties.put("RAFT_ADDRESS", LOCALHOST + ":" + this.raftPort); + } + + public void setRaftPeerList(List raftPeerList) { + String raftPeers = String.join(",", raftPeerList); + setProperty("RAFT_PEERS_LIST", raftPeers); + } + + public void setStoreCount(int storeCount) { + setProperty("STORE_COUNT", String.valueOf(storeCount)); + } + + public void setStoreGrpcList(List storeGrpcList) { + String storeGrpcLists = String.join(",", storeGrpcList); + setProperty("STORE_GRPC_LIST", storeGrpcLists); + } + + public String getRaftAddress() { + return LOCALHOST + ":" + this.raftPort; + } + + public String getGrpcAddress() { + return LOCALHOST + ":" + this.grpcPort; + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/ServerConfig.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/ServerConfig.java new file mode 100644 index 0000000000..569a11dddf --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/ServerConfig.java @@ -0,0 +1,54 @@ +/* + * 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.ct.config; + +import static org.apache.hugegraph.ct.base.ClusterConstant.CONFIG_FILE_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.LOCALHOST; +import static org.apache.hugegraph.ct.base.ClusterConstant.SERVER_PROPERTIES; +import static org.apache.hugegraph.ct.base.ClusterConstant.SERVER_TEMPLATE_FILE; +import static org.apache.hugegraph.ct.base.EnvUtil.getAvailablePort; + +import java.nio.file.Paths; + +import lombok.Getter; + +@Getter +public class ServerConfig extends AbstractConfig { + + private final int rpcPort; + private final int restPort; + + public ServerConfig() { + readTemplate(Paths.get(CONFIG_FILE_PATH + SERVER_TEMPLATE_FILE)); + this.fileName = SERVER_PROPERTIES; + this.rpcPort = getAvailablePort(); + this.restPort = getAvailablePort(); + properties.put("REST_SERVER_ADDRESS", LOCALHOST + ":" + this.restPort); + properties.put("RPC_PORT", String.valueOf(this.rpcPort)); + } + + public void setServerID(String serverID) { + setProperty("SERVER_ID", serverID); + } + + public void setRole(String role) { + setProperty("ROLE", role); + } +} + + diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/StoreConfig.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/StoreConfig.java new file mode 100644 index 0000000000..50495f18a5 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/config/StoreConfig.java @@ -0,0 +1,57 @@ +/* + * 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.ct.config; + +import static org.apache.hugegraph.ct.base.ClusterConstant.APPLICATION_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.CONFIG_FILE_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.LOCALHOST; +import static org.apache.hugegraph.ct.base.ClusterConstant.STORE_TEMPLATE_FILE; +import static org.apache.hugegraph.ct.base.EnvUtil.getAvailablePort; + +import java.nio.file.Paths; +import java.util.List; + +import lombok.Getter; + +@Getter +public class StoreConfig extends AbstractConfig { + + private final int raftPort; + private final int grpcPort; + private final int restPort; + + public StoreConfig() { + readTemplate(Paths.get(CONFIG_FILE_PATH + STORE_TEMPLATE_FILE)); + this.fileName = APPLICATION_FILE; + this.raftPort = getAvailablePort(); + this.grpcPort = getAvailablePort(); + this.restPort = getAvailablePort(); + properties.put("GRPC_PORT", String.valueOf(this.grpcPort)); + properties.put("REST_PORT", String.valueOf(this.restPort)); + properties.put("RAFT_ADDRESS", LOCALHOST + ":" + this.raftPort); + } + + public void setPDServerList(List pdServerList) { + String pdServers = String.join(",", pdServerList); + setProperty("PD_SERVER_ADDRESS", pdServers); + } + + public String getGrpcAddress() { + return LOCALHOST + ":" + this.grpcPort; + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/AbstractEnv.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/AbstractEnv.java new file mode 100644 index 0000000000..0c24860929 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/AbstractEnv.java @@ -0,0 +1,182 @@ +/* + * 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.ct.env; + +import static org.apache.hugegraph.ct.base.ClusterConstant.CONF_DIR; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hugegraph.ct.base.HGTestLogger; +import org.apache.hugegraph.ct.config.ClusterConfig; +import org.apache.hugegraph.ct.config.GraphConfig; +import org.apache.hugegraph.ct.config.PDConfig; +import org.apache.hugegraph.ct.config.ServerConfig; +import org.apache.hugegraph.ct.config.StoreConfig; +import org.apache.hugegraph.ct.node.PDNodeWrapper; +import org.apache.hugegraph.ct.node.ServerNodeWrapper; +import org.apache.hugegraph.ct.node.StoreNodeWrapper; +import org.slf4j.Logger; + +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractEnv implements BaseEnv { + + private static final Logger LOG = HGTestLogger.ENV_LOG; + + protected ClusterConfig clusterConfig; + protected List pdNodeWrappers; + protected List serverNodeWrappers; + protected List storeNodeWrappers; + @Setter + protected int cluster_id = 0; + + protected AbstractEnv() { + this.pdNodeWrappers = new ArrayList<>(); + this.serverNodeWrappers = new ArrayList<>(); + this.storeNodeWrappers = new ArrayList<>(); + } + + protected void init(int pdCnt, int storeCnt, int serverCnt) { + this.clusterConfig = new ClusterConfig(pdCnt, storeCnt, serverCnt); + for (int i = 0; i < pdCnt; i++) { + PDNodeWrapper pdNodeWrapper = new PDNodeWrapper(cluster_id, i); + PDConfig pdConfig = clusterConfig.getPDConfig(i); + pdNodeWrappers.add(pdNodeWrapper); + pdConfig.writeConfig(pdNodeWrapper.getNodePath() + CONF_DIR); + } + + for (int i = 0; i < storeCnt; i++) { + StoreNodeWrapper storeNodeWrapper = new StoreNodeWrapper(cluster_id, i); + StoreConfig storeConfig = clusterConfig.getStoreConfig(i); + storeNodeWrappers.add(storeNodeWrapper); + storeConfig.writeConfig(storeNodeWrapper.getNodePath() + CONF_DIR); + } + + for (int i = 0; i < serverCnt; i++) { + ServerNodeWrapper serverNodeWrapper = new ServerNodeWrapper(cluster_id, i); + serverNodeWrappers.add(serverNodeWrapper); + ServerConfig serverConfig = clusterConfig.getServerConfig(i); + serverConfig.setServerID(serverNodeWrapper.getID()); + GraphConfig graphConfig = clusterConfig.getGraphConfig(i); + if (i == 0) { + serverConfig.setRole("master"); + } else { + serverConfig.setRole("worker"); + } + serverConfig.writeConfig(serverNodeWrapper.getNodePath() + CONF_DIR); + graphConfig.writeConfig(serverNodeWrapper.getNodePath() + CONF_DIR); + } + } + + public void startCluster() { + for (PDNodeWrapper pdNodeWrapper : pdNodeWrappers) { + pdNodeWrapper.start(); + while (!pdNodeWrapper.isStarted()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + for (StoreNodeWrapper storeNodeWrapper : storeNodeWrappers) { + storeNodeWrapper.start(); + while (!storeNodeWrapper.isStarted()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + for (ServerNodeWrapper serverNodeWrapper : serverNodeWrappers) { + serverNodeWrapper.start(); + while (!serverNodeWrapper.isStarted()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + } + + public void stopCluster() { + for (ServerNodeWrapper serverNodeWrapper : serverNodeWrappers) { + serverNodeWrapper.stop(); + } + for (StoreNodeWrapper storeNodeWrapper : storeNodeWrappers) { + storeNodeWrapper.stop(); + } + for (PDNodeWrapper pdNodeWrapper : pdNodeWrappers) { + pdNodeWrapper.stop(); + } + } + + public ClusterConfig getConf() { + return this.clusterConfig; + } + + public List getPDRestAddrs() { + return clusterConfig.getPDRestAddrs(); + } + + public List getPDGrpcAddrs() { + return clusterConfig.getPDGrpcAddrs(); + } + + public List getStoreRestAddrs() { + return clusterConfig.getStoreRestAddrs(); + } + + public List getStoreGrpcAddrs() { + return clusterConfig.getStoreGrpcAddrs(); + } + + public List getServerRestAddrs() { + return clusterConfig.getServerRestAddrs(); + } + + public List getPDNodeDir() { + List nodeDirs = new ArrayList<>(); + for (PDNodeWrapper pdNodeWrapper : pdNodeWrappers) { + nodeDirs.add(pdNodeWrapper.getNodePath()); + } + return nodeDirs; + } + + public List getStoreNodeDir() { + List nodeDirs = new ArrayList<>(); + for (StoreNodeWrapper storeNodeWrapper : storeNodeWrappers) { + nodeDirs.add(storeNodeWrapper.getNodePath()); + } + return nodeDirs; + } + + public List getServerNodeDir() { + List nodeDirs = new ArrayList<>(); + for (ServerNodeWrapper serverNodeWrapper : serverNodeWrappers) { + nodeDirs.add(serverNodeWrapper.getNodePath()); + } + return nodeDirs; + } + +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/BaseEnv.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/BaseEnv.java new file mode 100644 index 0000000000..f6c4ba5fb6 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/BaseEnv.java @@ -0,0 +1,49 @@ +/* + * 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.ct.env; + +import java.util.List; + +import org.apache.hugegraph.ct.config.ClusterConfig; + +public interface BaseEnv { + + /* init the cluster environment with simple mode */ + void startCluster(); + + /* clear the cluster env and all config*/ + void stopCluster(); + + ClusterConfig getConf(); + + void init(); + + List getPDRestAddrs(); + + List getPDGrpcAddrs(); + + List getStoreRestAddrs(); + + List getServerRestAddrs(); + + List getPDNodeDir(); + + List getStoreNodeDir(); + + List getServerNodeDir(); +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/EnvFactory.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/EnvFactory.java new file mode 100644 index 0000000000..a716697c5a --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/EnvFactory.java @@ -0,0 +1,46 @@ +/* + * 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.ct.env; + +import org.apache.hugegraph.ct.base.EnvType; +import org.apache.hugegraph.ct.base.HGTestLogger; +import org.slf4j.Logger; + +public class EnvFactory { + + private static final Logger LOG = HGTestLogger.ENV_LOG; + private static BaseEnv env; + + public static BaseEnv getEnv() { + if (env == null) { + EnvType envType = EnvType.getSystemEnvType(); + switch (envType) { + case SingleNode: + env = new SimpleEnv(); + break; + case MultiNode: + env = new MultiNodeEnv(); + break; + default: + LOG.error("No such env type: {}", envType); + } + } + return env; + } + +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/MultiNodeEnv.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/MultiNodeEnv.java new file mode 100644 index 0000000000..83a540f26a --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/MultiNodeEnv.java @@ -0,0 +1,36 @@ +/* + * 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.ct.env; + +public class MultiNodeEnv extends AbstractEnv { + + public MultiNodeEnv() { + super(); + this.init(); + } + + public MultiNodeEnv(int pdNum, int storeNum, int serverNum) { + super(); + super.init(pdNum, storeNum, serverNum); + } + + @Override + public void init() { + super.init(3, 3, 3); + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/SimpleEnv.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/SimpleEnv.java new file mode 100644 index 0000000000..595ed0fbe1 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/env/SimpleEnv.java @@ -0,0 +1,30 @@ +/* + * 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.ct.env; + +public class SimpleEnv extends AbstractEnv { + + public SimpleEnv() { + super(); + init(); + } + + public void init() { + super.init(1, 1, 1); + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/AbstractNodeWrapper.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/AbstractNodeWrapper.java new file mode 100644 index 0000000000..8236bb1392 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/AbstractNodeWrapper.java @@ -0,0 +1,191 @@ +/* + * 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.ct.node; + +import static org.apache.hugegraph.ct.base.ClusterConstant.CT_PACKAGE_PATH; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.file.PathUtils; +import org.apache.hugegraph.ct.base.ClusterConstant; +import org.apache.hugegraph.ct.base.EnvUtil; +import org.apache.hugegraph.ct.base.HGTestLogger; +import org.slf4j.Logger; + +import lombok.Getter; + +public abstract class AbstractNodeWrapper implements BaseNodeWrapper { + + protected final Logger LOG = HGTestLogger.NODE_LOG; + + protected int clusterIndex; + @Getter + protected String workPath; + @Getter + protected String configPath; + protected Process instance; + protected int index; + protected List fileNames; + protected String startLine; + + public AbstractNodeWrapper() { + this.clusterIndex = 1; + fileNames = new ArrayList<>(); + this.configPath = getNodePath(); + } + + public AbstractNodeWrapper(int clusterIndex, int index) { + this.clusterIndex = clusterIndex; + this.index = index; + fileNames = new ArrayList<>(); + this.configPath = getNodePath(); + } + + /** + * Node Dir should be created before changing Config + */ + public void createNodeDir(Path sourcePath, String destDir) { + try { + try { + if (!new File(destDir).exists()) { + FileUtils.createParentDirectories(new File(destDir)); + } + } catch (NoSuchFileException fileException) { + // Ignored + } + // To avoid following symbolic links + try (Stream stream = Files.walk(sourcePath)) { + stream.forEach(source -> { + Path relativePath = sourcePath.relativize(source); + Path destination = Paths.get(destDir).resolve(relativePath); + if (fileNames.contains(relativePath.toString())) { + EnvUtil.copyFileToDestination(source, destination); + } + }); + } + } catch (IOException ioException) { + LOG.error("Got error copying files to node destination dir", ioException); + throw new AssertionError(); + } + } + + public void createLogDir() { + String logPath = getLogPath(); + try { + FileUtils.createParentDirectories(new File(logPath)); + } catch (IOException e) { + LOG.error("Create log dir failed", e); + throw new AssertionError(); + } + } + + public void deleteDir() { + try { + PathUtils.deleteDirectory(Paths.get(getNodePath())); + } catch (IOException ex) { + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + LOG.error("Fail to delete node file", e); + throw new AssertionError("Delete node dir failed. " + e); + } + } + } + + /** + * @return (user.dir).id + */ + @Override + public String getNodePath() { + return CT_PACKAGE_PATH + getID() + File.separator; + } + + @Override + public String getLogPath() { + return getNodePath() + ClusterConstant.LOG + File.separator + getID() + "-start.log"; + } + + @Override + public void updateWorkPath(String workPath) { + this.workPath = workPath; + } + + @Override + public void updateConfigPath(String ConfigPath) { + this.configPath = ConfigPath; + } + + @Override + public boolean isStarted() { + try (Scanner sc = new Scanner(new FileReader(getLogPath()))) { + while (sc.hasNextLine()) { + String line = sc.nextLine(); + if (line.contains(startLine)) return true; + } + } catch (FileNotFoundException ignored) { + } + return false; + } + + public void stop() { + if (this.instance == null) { + return; + } + this.instance.destroy(); + try { + if (!this.instance.waitFor(20, TimeUnit.SECONDS)) { + this.instance.destroyForcibly().waitFor(10, TimeUnit.SECONDS); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + LOG.error("Waiting node to shutdown error.", e); + } + deleteDir(); + } + + public boolean isAlive() { + return this.instance.isAlive(); + } + + protected ProcessBuilder runCmd(List startCmd, File stdoutFile) throws IOException { + FileUtils.write(stdoutFile, + String.join(" ", startCmd) + System.lineSeparator() + System.lineSeparator(), + StandardCharsets.UTF_8, true); + ProcessBuilder processBuilder = new ProcessBuilder(startCmd) + .redirectOutput(ProcessBuilder.Redirect.appendTo(stdoutFile)) + .redirectError(ProcessBuilder.Redirect.appendTo(stdoutFile)); + processBuilder.directory(new File(configPath)); + return processBuilder; + } + +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/BaseNodeWrapper.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/BaseNodeWrapper.java new file mode 100644 index 0000000000..f428b227c4 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/BaseNodeWrapper.java @@ -0,0 +1,39 @@ +/* + * 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.ct.node; + +public interface BaseNodeWrapper { + + void start(); + + void stop(); + + boolean isAlive(); + + String getID(); + + String getNodePath(); + + String getLogPath(); + + void updateWorkPath(String workPath); + + void updateConfigPath(String ConfigPath); + + boolean isStarted(); +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/PDNodeWrapper.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/PDNodeWrapper.java new file mode 100644 index 0000000000..a89c614c4c --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/PDNodeWrapper.java @@ -0,0 +1,93 @@ +/* + * 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.ct.node; + +import static org.apache.hugegraph.ct.base.ClusterConstant.CONF_DIR; +import static org.apache.hugegraph.ct.base.ClusterConstant.JAVA_CMD; +import static org.apache.hugegraph.ct.base.ClusterConstant.LOG4J_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.PD_JAR_PREFIX; +import static org.apache.hugegraph.ct.base.ClusterConstant.PD_LIB_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.PD_TEMPLATE_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.getFileInDir; +import static org.apache.hugegraph.ct.base.ClusterConstant.isJava11OrHigher; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class PDNodeWrapper extends AbstractNodeWrapper { + + public PDNodeWrapper() { + super(); + fileNames = new ArrayList<>(Arrays.asList(LOG4J_FILE)); + this.workPath = PD_LIB_PATH; + this.startLine = "Hugegraph-pd started."; + createNodeDir(Paths.get(PD_TEMPLATE_PATH), getNodePath() + CONF_DIR + File.separator); + createLogDir(); + } + + public PDNodeWrapper(int clusterIndex, int index) { + super(clusterIndex, index); + this.fileNames = new ArrayList<>(Arrays.asList(LOG4J_FILE)); + this.workPath = PD_LIB_PATH; + this.startLine = "Hugegraph-pd started."; + createNodeDir(Paths.get(PD_TEMPLATE_PATH), getNodePath() + CONF_DIR + File.separator); + createLogDir(); + } + + /* + workPath is path of JAR package, configPath is path of config files + */ + @Override + public void start() { + try { + File stdoutFile = new File(getLogPath()); + List startCmd = new ArrayList<>(); + startCmd.add(JAVA_CMD); + if (!isJava11OrHigher()) { + LOG.error("Please make sure that the JDK is installed and the version >= 11"); + return; + } + + String pdNodeJarPath = getFileInDir(workPath, PD_JAR_PREFIX); + startCmd.addAll(Arrays.asList( + "-Dname=HugeGraphPD" + this.index, + "-Xms512m", + "-Xmx4g", + "-XX:+HeapDumpOnOutOfMemoryError", + "-XX:HeapDumpPath=" + configPath + "logs", + "-Dlog4j.configurationFile=" + configPath + File.separator + + CONF_DIR + File.separator + "log4j2.xml", + "-Dspring.config.location=" + configPath + CONF_DIR + File.separator + + "application.yml", + "-jar", pdNodeJarPath)); + ProcessBuilder processBuilder = runCmd(startCmd, stdoutFile); + this.instance = processBuilder.start(); + } catch (IOException ex) { + throw new AssertionError("Start node failed. " + ex); + } + } + + @Override + public String getID() { + return "PD" + this.index; + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/ServerNodeWrapper.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/ServerNodeWrapper.java new file mode 100644 index 0000000000..e39bc39557 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/ServerNodeWrapper.java @@ -0,0 +1,105 @@ +/* + * 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.ct.node; + +import static org.apache.hugegraph.ct.base.ClusterConstant.CONF_DIR; +import static org.apache.hugegraph.ct.base.ClusterConstant.EMPTY_SAMPLE_GROOVY_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.EXAMPLE_GROOVY_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.EXT_DIR; +import static org.apache.hugegraph.ct.base.ClusterConstant.GREMLIN_DRIVER_SETTING_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.GREMLIN_SERVER_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.JAVA_CMD; +import static org.apache.hugegraph.ct.base.ClusterConstant.LIB_DIR; +import static org.apache.hugegraph.ct.base.ClusterConstant.LOG4J_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.PLUGINS_DIR; +import static org.apache.hugegraph.ct.base.ClusterConstant.REMOTE_OBJECTS_SETTING_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.REMOTE_SETTING_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.SERVER_LIB_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.SERVER_PACKAGE_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.SERVER_TEMPLATE_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.isJava11OrHigher; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ServerNodeWrapper extends AbstractNodeWrapper { + + public ServerNodeWrapper(int clusterIndex, int index) { + super(clusterIndex, index); + this.fileNames = new ArrayList<>( + List.of(LOG4J_FILE, GREMLIN_SERVER_FILE, GREMLIN_DRIVER_SETTING_FILE, + REMOTE_SETTING_FILE, REMOTE_OBJECTS_SETTING_FILE)); + this.workPath = SERVER_LIB_PATH; + createNodeDir(Paths.get(SERVER_TEMPLATE_PATH), getNodePath() + CONF_DIR + File.separator); + this.fileNames = new ArrayList<>(List.of(EMPTY_SAMPLE_GROOVY_FILE, EXAMPLE_GROOVY_FILE)); + this.startLine = "INFO: [HttpServer] Started."; + createNodeDir(Paths.get(SERVER_PACKAGE_PATH), getNodePath()); + createLogDir(); + } + + private static void addJarsToClasspath(File directory, List classpath) { + if (directory.exists() && directory.isDirectory()) { + File[] files = directory.listFiles((dir, name) -> name.endsWith(".jar")); + if (files != null) { + for (File file : files) { + classpath.add(file.getAbsolutePath()); + } + } + } + } + + @Override + public void start() { + try { + File stdoutFile = new File(getLogPath()); + List startCmd = new ArrayList<>(); + startCmd.add(JAVA_CMD); + if (!isJava11OrHigher()) { + LOG.error("Please make sure that the JDK is installed and the version >= 11"); + return; + } + + List classpath = new ArrayList<>(); + addJarsToClasspath(new File(workPath + LIB_DIR), classpath); + addJarsToClasspath(new File(workPath + EXT_DIR), classpath); + addJarsToClasspath(new File(workPath + PLUGINS_DIR), classpath); + String storeClassPath = String.join(":", classpath); + + startCmd.addAll(Arrays.asList( + "-Dname=HugeGraphServer" + this.index, + "--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED", + "-cp", storeClassPath, + "org.apache.hugegraph.dist.HugeGraphServer", + "./conf/gremlin-server.yaml", + "./conf/rest-server.properties")); + ProcessBuilder processBuilder = runCmd(startCmd, stdoutFile); + this.instance = processBuilder.start(); + } catch (IOException ex) { + throw new AssertionError("Started server node failed. " + ex); + } + } + + @Override + public String getID() { + return "Server" + this.index; + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/StoreNodeWrapper.java b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/StoreNodeWrapper.java new file mode 100644 index 0000000000..1cb0f67eae --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-minicluster/src/main/java/org/apache/hugegraph/ct/node/StoreNodeWrapper.java @@ -0,0 +1,94 @@ +/* + * 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.ct.node; + +import static org.apache.hugegraph.ct.base.ClusterConstant.CONF_DIR; +import static org.apache.hugegraph.ct.base.ClusterConstant.JAVA_CMD; +import static org.apache.hugegraph.ct.base.ClusterConstant.LOG4J_FILE; +import static org.apache.hugegraph.ct.base.ClusterConstant.STORE_JAR_PREFIX; +import static org.apache.hugegraph.ct.base.ClusterConstant.STORE_LIB_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.STORE_TEMPLATE_PATH; +import static org.apache.hugegraph.ct.base.ClusterConstant.getFileInDir; +import static org.apache.hugegraph.ct.base.ClusterConstant.isJava11OrHigher; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class StoreNodeWrapper extends AbstractNodeWrapper { + + public StoreNodeWrapper() { + super(); + this.fileNames = new ArrayList<>(List.of(LOG4J_FILE)); + this.workPath = STORE_LIB_PATH; + this.startLine = "o.a.h.s.n.StoreNodeApplication - Starting StoreNodeApplication"; + createNodeDir(Paths.get(STORE_TEMPLATE_PATH), getNodePath() + CONF_DIR + File.separator); + createLogDir(); + } + + public StoreNodeWrapper(int clusterId, int index) { + super(clusterId, index); + this.fileNames = new ArrayList<>(List.of(LOG4J_FILE)); + this.workPath = STORE_LIB_PATH; + this.startLine = "o.a.h.s.n.StoreNodeApplication - Starting StoreNodeApplication"; + createNodeDir(Paths.get(STORE_TEMPLATE_PATH), getNodePath() + CONF_DIR + File.separator); + createLogDir(); + } + + @Override + public void start() { + try { + File stdoutFile = new File(getLogPath()); + List startCmd = new ArrayList<>(); + startCmd.add(JAVA_CMD); + if (!isJava11OrHigher()) { + LOG.error("Please make sure that the JDK is installed and the version >= 11"); + return; + } + + String storeNodeJarPath = getFileInDir(workPath, STORE_JAR_PREFIX); + startCmd.addAll(Arrays.asList( + "-Dname=HugeGraphStore" + this.index, + "-Dlog4j.configurationFile=" + configPath + CONF_DIR + + File.separator + "log4j2.xml", + "-Dfastjson.parser.safeMode=true", + "-Xms512m", + "-Xmx2048m", + "-XX:MetaspaceSize=256M", + "-XX:+UseG1GC", + "-XX:+ParallelRefProcEnabled", + "-XX:+HeapDumpOnOutOfMemoryError", + "-XX:HeapDumpPath=" + configPath + "logs", + "-Dspring.config.location=" + configPath + CONF_DIR + + File.separator + "application.yml", + "-jar", storeNodeJarPath)); + ProcessBuilder processBuilder = runCmd(startCmd, stdoutFile); + this.instance = processBuilder.start(); + } catch (IOException ex) { + throw new AssertionError("Start node failed. " + ex); + } + } + + @Override + public String getID() { + return "Store" + this.index; + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/pom.xml b/hugegraph-cluster-test/hugegraph-clustertest-test/pom.xml new file mode 100644 index 0000000000..c888404545 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/pom.xml @@ -0,0 +1,98 @@ + + + + + 4.0.0 + + org.apache.hugegraph + hugegraph-cluster-test + ${revision} + + + hugegraph-clustertest-test + + + 11 + 11 + UTF-8 + + + + org.apache.hugegraph + hugegraph-clustertest-minicluster + ${revision} + compile + + + + org.apache.hugegraph + hugegraph-client + ${toolchain.vision} + + + org.apache.hugegraph + hg-pd-client + ${revision} + + + junit + junit + 4.13.2 + compile + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.20 + + + simple-cluster-test + + ${basedir}/src/main/java/ + + ${basedir}/target/classes/ + + + **/SimpleClusterSuiteTest.java + + + + + multi-cluster-test + + ${basedir}/src/main/java/ + + ${basedir}/target/classes/ + + + **/MultiClusterSuiteTest.java + + + + + + + + + diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/BaseMultiClusterTest.java b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/BaseMultiClusterTest.java new file mode 100644 index 0000000000..59394101c2 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/BaseMultiClusterTest.java @@ -0,0 +1,64 @@ +/* + * 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.MultiClusterTest; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +import org.apache.hugegraph.ct.env.BaseEnv; +import org.apache.hugegraph.ct.env.MultiNodeEnv; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +/** + * MultiNode Test generate the cluster env with 3 pd node + 3 store node + 3 server node. + * Or you can set different num of nodes by using env = new MultiNodeEnv(pdNum, storeNum, serverNum) + * All nodes are deployed in ports generated randomly, the application of nodes are stored + * in /apache-hugegraph-ct-incubating-1.5.0, you can visit each node with rest api. + */ +public class BaseMultiClusterTest { + + protected static BaseEnv env; + protected static Process p; + + @BeforeClass + public static void initEnv() { + env = new MultiNodeEnv(); + env.startCluster(); + } + + @AfterClass + public static void clearEnv() { + env.stopCluster(); + } + + protected String execCmd(String[] cmds) throws IOException { + ProcessBuilder process = new ProcessBuilder(cmds); + p = process.start(); + BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line); + builder.append(System.lineSeparator()); + } + p.destroy(); + return builder.toString(); + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/MultiClusterDeployTest.java b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/MultiClusterDeployTest.java new file mode 100644 index 0000000000..0318df1ad0 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/MultiClusterDeployTest.java @@ -0,0 +1,203 @@ +/* + * 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.MultiClusterTest; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import org.apache.hugegraph.driver.GraphManager; +import org.apache.hugegraph.driver.GremlinManager; +import org.apache.hugegraph.driver.HugeClient; +import org.apache.hugegraph.driver.SchemaManager; +import org.apache.hugegraph.pd.client.PDClient; +import org.apache.hugegraph.pd.client.PDConfig; +import org.apache.hugegraph.pd.common.PDException; +import org.apache.hugegraph.structure.constant.T; +import org.apache.hugegraph.structure.graph.Edge; +import org.apache.hugegraph.structure.graph.Path; +import org.apache.hugegraph.structure.graph.Vertex; +import org.apache.hugegraph.structure.gremlin.Result; +import org.apache.hugegraph.structure.gremlin.ResultSet; +import org.junit.Assert; +import org.junit.Test; + +public class MultiClusterDeployTest extends BaseMultiClusterTest { + + @Test + public void testPDNodesDeployment() { + try { + List addrs = env.getPDGrpcAddrs(); + for (String addr : addrs) { + PDConfig pdConfig = PDConfig.of(addr); + PDClient pdClient = PDClient.create(pdConfig); + pdClient.dbCompaction(); + } + assert true; + } catch (PDException e) { + assert false; + } + } + + @Test + public void testStoreNodesDeployment() throws IOException { + List addrs = env.getStoreRestAddrs(); + for (String addr : addrs) { + String[] cmds = {"curl", addr}; + // TODO: why not use the sb param? + StringBuilder sb = new StringBuilder(); + for (String cmd : cmds) { + sb.append(cmd).append(" "); + } + String responseMsg = execCmd(cmds); + Assert.assertTrue(responseMsg.startsWith("{")); + } + } + + @Test + public void testServerNodesDeployment() { + List addrs = env.getServerRestAddrs(); + for (String addr : addrs) { + HugeClient hugeClient = HugeClient.builder("http://" + addr, "hugegraph") + .build(); + SchemaManager schema = hugeClient.schema(); + + schema.propertyKey("name").asText().ifNotExist().create(); + schema.propertyKey("age").asInt().ifNotExist().create(); + schema.propertyKey("city").asText().ifNotExist().create(); + schema.propertyKey("weight").asDouble().ifNotExist().create(); + schema.propertyKey("lang").asText().ifNotExist().create(); + schema.propertyKey("date").asDate().ifNotExist().create(); + schema.propertyKey("price").asInt().ifNotExist().create(); + + schema.vertexLabel("person") + .properties("name", "age", "city") + .primaryKeys("name") + .ifNotExist() + .create(); + + schema.vertexLabel("software") + .properties("name", "lang", "price") + .primaryKeys("name") + .ifNotExist() + .create(); + + schema.indexLabel("personByCity") + .onV("person") + .by("city") + .secondary() + .ifNotExist() + .create(); + + schema.indexLabel("personByAgeAndCity") + .onV("person") + .by("age", "city") + .secondary() + .ifNotExist() + .create(); + + schema.indexLabel("softwareByPrice") + .onV("software") + .by("price") + .range() + .ifNotExist() + .create(); + + schema.edgeLabel("knows") + .sourceLabel("person") + .targetLabel("person") + .properties("date", "weight") + .ifNotExist() + .create(); + + schema.edgeLabel("created") + .sourceLabel("person").targetLabel("software") + .properties("date", "weight") + .ifNotExist() + .create(); + + schema.indexLabel("createdByDate") + .onE("created") + .by("date") + .secondary() + .ifNotExist() + .create(); + + schema.indexLabel("createdByWeight") + .onE("created") + .by("weight") + .range() + .ifNotExist() + .create(); + + schema.indexLabel("knowsByWeight") + .onE("knows") + .by("weight") + .range() + .ifNotExist() + .create(); + + GraphManager graph = hugeClient.graph(); + Vertex marko = graph.addVertex(T.LABEL, "person", "name", "marko", + "age", 29, "city", "Beijing"); + Vertex vadas = graph.addVertex(T.LABEL, "person", "name", "vadas", + "age", 27, "city", "Hongkong"); + Vertex lop = graph.addVertex(T.LABEL, "software", "name", "lop", + "lang", "java", "price", 328); + Vertex josh = graph.addVertex(T.LABEL, "person", "name", "josh", + "age", 32, "city", "Beijing"); + Vertex ripple = graph.addVertex(T.LABEL, "software", "name", "ripple", + "lang", "java", "price", 199); + Vertex peter = graph.addVertex(T.LABEL, "person", "name", "peter", + "age", 35, "city", "Shanghai"); + + marko.addEdge("knows", vadas, "date", "2016-01-10", "weight", 0.5); + marko.addEdge("knows", josh, "date", "2013-02-20", "weight", 1.0); + marko.addEdge("created", lop, "date", "2017-12-10", "weight", 0.4); + josh.addEdge("created", lop, "date", "2009-11-11", "weight", 0.4); + josh.addEdge("created", ripple, "date", "2017-12-10", "weight", 1.0); + peter.addEdge("created", lop, "date", "2017-03-24", "weight", 0.2); + + GremlinManager gremlin = hugeClient.gremlin(); + System.out.println("==== Path ===="); + ResultSet resultSet = gremlin.gremlin("g.V().outE().path()").execute(); + Iterator results = resultSet.iterator(); + results.forEachRemaining(result -> { + System.out.println(result.getObject().getClass()); + Object object = result.getObject(); + if (object instanceof Vertex) { + System.out.println(((Vertex) object).id()); + } else if (object instanceof Edge) { + System.out.println(((Edge) object).id()); + } else if (object instanceof Path) { + List elements = ((Path) object).objects(); + elements.forEach(element -> { + System.out.println(element.getClass()); + System.out.println(element); + }); + } else { + System.out.println(object); + } + }); + + hugeClient.close(); + assert true; + break; + } + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/MultiClusterFileTest.java b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/MultiClusterFileTest.java new file mode 100644 index 0000000000..d74155ad16 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/MultiClusterFileTest.java @@ -0,0 +1,47 @@ +/* + * 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.MultiClusterTest; + +import java.io.File; + +import org.junit.Assert; +import org.junit.Test; + +public class MultiClusterFileTest extends BaseMultiClusterTest { + + @Test + public void checkPDNodeDir() { + for (String nodeDir : env.getPDNodeDir()) { + Assert.assertTrue(new File(nodeDir).isDirectory()); + } + } + + @Test + public void checkStoreNodeDir() { + for (String nodeDir : env.getStoreNodeDir()) { + Assert.assertTrue(new File(nodeDir).isDirectory()); + } + } + + @Test + public void checkServerNodeDir() { + for (String nodeDir : env.getServerNodeDir()) { + Assert.assertTrue(new File(nodeDir).isDirectory()); + } + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/MultiClusterSuiteTest.java b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/MultiClusterSuiteTest.java new file mode 100644 index 0000000000..6e55cdd200 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/MultiClusterSuiteTest.java @@ -0,0 +1,33 @@ +/* + * 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.MultiClusterTest; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +import lombok.extern.slf4j.Slf4j; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + MultiClusterDeployTest.class, + MultiClusterFileTest.class, +}) +@Slf4j +public class MultiClusterSuiteTest { + +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/BaseSimpleTest.java b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/BaseSimpleTest.java new file mode 100644 index 0000000000..61954de811 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/BaseSimpleTest.java @@ -0,0 +1,69 @@ +/* + * 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.SimpleClusterTest; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +import org.apache.hugegraph.ct.env.BaseEnv; +import org.apache.hugegraph.ct.env.SimpleEnv; +import org.apache.hugegraph.driver.HugeClient; +import org.apache.hugegraph.pd.client.PDClient; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +/** + * Simple Test generate the cluster env with 1 pd node + 1 store node + 1 server node. + * All nodes are deployed in ports generated randomly; The application of nodes is stored + * in /apache-hugegraph-ct-incubating-1.5.0, you can visit each node with rest api. + */ +public class BaseSimpleTest { + + protected static BaseEnv env; + protected static Process p; + protected static PDClient pdClient; + protected static HugeClient hugeClient; + + @BeforeClass + public static void initEnv() { + env = new SimpleEnv(); + env.startCluster(); + } + + @AfterClass + public static void clearEnv() throws InterruptedException { + env.stopCluster(); + Thread.sleep(2000); + } + + protected String execCmd(String[] cmds) throws IOException { + ProcessBuilder process = new ProcessBuilder(cmds); + p = process.start(); + BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line); + builder.append(System.lineSeparator()); + } + p.destroy(); + return builder.toString(); + } + +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/SimpleClusterDeployTest.java b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/SimpleClusterDeployTest.java new file mode 100644 index 0000000000..61a73ff0f4 --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/SimpleClusterDeployTest.java @@ -0,0 +1,200 @@ +/* + * 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.SimpleClusterTest; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import org.apache.hugegraph.driver.GraphManager; +import org.apache.hugegraph.driver.GremlinManager; +import org.apache.hugegraph.driver.HugeClient; +import org.apache.hugegraph.driver.SchemaManager; +import org.apache.hugegraph.pd.client.PDClient; +import org.apache.hugegraph.pd.client.PDConfig; +import org.apache.hugegraph.pd.common.PDException; +import org.apache.hugegraph.structure.constant.T; +import org.apache.hugegraph.structure.graph.Edge; +import org.apache.hugegraph.structure.graph.Path; +import org.apache.hugegraph.structure.graph.Vertex; +import org.apache.hugegraph.structure.gremlin.Result; +import org.apache.hugegraph.structure.gremlin.ResultSet; +import org.junit.Assert; +import org.junit.Test; + +public class SimpleClusterDeployTest extends BaseSimpleTest { + + @Test + public void testPDNodesDeployment() { + try { + List addrs = env.getPDGrpcAddrs(); + for (String addr : addrs) { + PDConfig pdConfig = PDConfig.of(addr); + pdClient = PDClient.create(pdConfig); + pdClient.dbCompaction(); + } + assert true; + } catch (PDException pdException) { + assert false; + } + } + + @Test + public void testStoreNodesDeployment() throws IOException { + List addrs = env.getStoreRestAddrs(); + for (String addr : addrs) { + String[] cmds = {"curl", addr}; + // TODO: what's the purpose of this? + StringBuilder sb = new StringBuilder(); + for (String cmd : cmds) { + sb.append(cmd).append(" "); + } + String responseMsg = execCmd(cmds); + Assert.assertTrue(responseMsg.startsWith("{")); + } + } + + @Test + public void testServerNodesDeployment() { + List addrs = env.getServerRestAddrs(); + for (String addr : addrs) { + hugeClient = HugeClient.builder("http://" + addr, "hugegraph").build(); + SchemaManager schema = hugeClient.schema(); + + schema.propertyKey("name").asText().ifNotExist().create(); + schema.propertyKey("age").asInt().ifNotExist().create(); + schema.propertyKey("city").asText().ifNotExist().create(); + schema.propertyKey("weight").asDouble().ifNotExist().create(); + schema.propertyKey("lang").asText().ifNotExist().create(); + schema.propertyKey("date").asDate().ifNotExist().create(); + schema.propertyKey("price").asInt().ifNotExist().create(); + + schema.vertexLabel("person") + .properties("name", "age", "city") + .primaryKeys("name") + .ifNotExist() + .create(); + + schema.vertexLabel("software") + .properties("name", "lang", "price") + .primaryKeys("name") + .ifNotExist() + .create(); + + schema.indexLabel("personByCity") + .onV("person") + .by("city") + .secondary() + .ifNotExist() + .create(); + + schema.indexLabel("personByAgeAndCity") + .onV("person") + .by("age", "city") + .secondary() + .ifNotExist() + .create(); + + schema.indexLabel("softwareByPrice") + .onV("software") + .by("price") + .range() + .ifNotExist() + .create(); + + schema.edgeLabel("knows") + .sourceLabel("person") + .targetLabel("person") + .properties("date", "weight") + .ifNotExist() + .create(); + + schema.edgeLabel("created") + .sourceLabel("person").targetLabel("software") + .properties("date", "weight") + .ifNotExist() + .create(); + + schema.indexLabel("createdByDate") + .onE("created") + .by("date") + .secondary() + .ifNotExist() + .create(); + + schema.indexLabel("createdByWeight") + .onE("created") + .by("weight") + .range() + .ifNotExist() + .create(); + + schema.indexLabel("knowsByWeight") + .onE("knows") + .by("weight") + .range() + .ifNotExist() + .create(); + + GraphManager graph = hugeClient.graph(); + Vertex marko = graph.addVertex(T.LABEL, "person", "name", "marko", + "age", 29, "city", "Beijing"); + Vertex vadas = graph.addVertex(T.LABEL, "person", "name", "vadas", + "age", 27, "city", "Hongkong"); + Vertex lop = graph.addVertex(T.LABEL, "software", "name", "lop", + "lang", "java", "price", 328); + Vertex josh = graph.addVertex(T.LABEL, "person", "name", "josh", + "age", 32, "city", "Beijing"); + Vertex ripple = graph.addVertex(T.LABEL, "software", "name", "ripple", + "lang", "java", "price", 199); + Vertex peter = graph.addVertex(T.LABEL, "person", "name", "peter", + "age", 35, "city", "Shanghai"); + + marko.addEdge("knows", vadas, "date", "2016-01-10", "weight", 0.5); + marko.addEdge("knows", josh, "date", "2013-02-20", "weight", 1.0); + marko.addEdge("created", lop, "date", "2017-12-10", "weight", 0.4); + josh.addEdge("created", lop, "date", "2009-11-11", "weight", 0.4); + josh.addEdge("created", ripple, "date", "2017-12-10", "weight", 1.0); + peter.addEdge("created", lop, "date", "2017-03-24", "weight", 0.2); + + GremlinManager gremlin = hugeClient.gremlin(); + System.out.println("==== Path ===="); + ResultSet resultSet = gremlin.gremlin("g.V().outE().path()").execute(); + Iterator results = resultSet.iterator(); + results.forEachRemaining(result -> { + System.out.println(result.getObject().getClass()); + Object object = result.getObject(); + if (object instanceof Vertex) { + System.out.println(((Vertex) object).id()); + } else if (object instanceof Edge) { + System.out.println(((Edge) object).id()); + } else if (object instanceof Path) { + List elements = ((Path) object).objects(); + elements.forEach(element -> { + System.out.println(element.getClass()); + System.out.println(element); + }); + } else { + System.out.println(object); + } + }); + + hugeClient.close(); + } + } +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/SimpleClusterFileTest.java b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/SimpleClusterFileTest.java new file mode 100644 index 0000000000..1cae2bcdba --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/SimpleClusterFileTest.java @@ -0,0 +1,48 @@ +/* + * 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.SimpleClusterTest; + +import java.io.File; + +import org.junit.Assert; +import org.junit.Test; + +public class SimpleClusterFileTest extends BaseSimpleTest { + + @Test + public void checkPDNodeDir() { + for (String nodeDir : env.getPDNodeDir()) { + Assert.assertTrue(new File(nodeDir).isDirectory()); + } + } + + @Test + public void checkStoreNodeDir() { + for (String nodeDir : env.getStoreNodeDir()) { + Assert.assertTrue(new File(nodeDir).isDirectory()); + } + } + + @Test + public void checkServerNodeDir() { + for (String nodeDir : env.getServerNodeDir()) { + Assert.assertTrue(new File(nodeDir).isDirectory()); + } + } + +} diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/SimpleClusterSuiteTest.java b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/SimpleClusterSuiteTest.java new file mode 100644 index 0000000000..7f24d8b46c --- /dev/null +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/SimpleClusterSuiteTest.java @@ -0,0 +1,33 @@ +/* + * 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.SimpleClusterTest; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +import lombok.extern.slf4j.Slf4j; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + SimpleClusterDeployTest.class, + SimpleClusterFileTest.class, +}) +@Slf4j +public class SimpleClusterSuiteTest { + +} diff --git a/hugegraph-cluster-test/pom.xml b/hugegraph-cluster-test/pom.xml new file mode 100644 index 0000000000..fcc409d6ad --- /dev/null +++ b/hugegraph-cluster-test/pom.xml @@ -0,0 +1,139 @@ + + + + + 4.0.0 + + hugegraph-cluster-test + ${revision} + pom + + + org.apache.hugegraph + hugegraph + ${revision} + ../pom.xml + + + + hugegraph-clustertest-minicluster + hugegraph-clustertest-dist + hugegraph-clustertest-test + + + + 11 + 11 + UTF-8 + apache-${release.name}-ct-incubating-${project.version} + + + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + junit + junit + + 4.13.2 + + + + + + + org.apache.maven.plugins + maven-clean-plugin + + + + ${project.basedir}/ + + *.tar + *.tar.gz + .flattened-pom.xml + ${final.name}/** + + false + + + ${final.name} + + + + + + + + + + simple-cluster-test + + true + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.20 + + + simple-cluster-test + + test + + test + + + + + + + + multi-cluster-test + + true + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.20 + + + multi-cluster-test + + test + + test + + + + + + + + + diff --git a/hugegraph-commons/README.md b/hugegraph-commons/README.md new file mode 100644 index 0000000000..4ec2ebb5bb --- /dev/null +++ b/hugegraph-commons/README.md @@ -0,0 +1,66 @@ +# hugegraph-commons + +[![License](https://img.shields.io/badge/license-Apache%202-0E78BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) +[![codecov](https://codecov.io/gh/hugegraph/hugegraph-common/branch/master/graph/badge.svg)](https://codecov.io/gh/hugegraph/hugegraph-common) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.hugegraph/hugegraph-common/badge.svg)](https://mvnrepository.com/artifact/org.apache.hugegraph/hugegraph-common) +[![CodeQL](https://github.com/apache/incubator-hugegraph-commons/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/apache/incubator-hugegraph-commons/actions/workflows/codeql-analysis.yml) +[![hugegraph-commons ci](https://github.com/apache/incubator-hugegraph-commons/actions/workflows/ci.yml/badge.svg)](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 + + org.apache.hugegraph + hugegraph-common + 1.2.0 + +``` + +## 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! + +[![contributors graph](https://contrib.rocks/image?repo=apache/hugegraph-commons)](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. + + QR png diff --git a/hugegraph-commons/hugegraph-common/README.md b/hugegraph-commons/hugegraph-common/README.md new file mode 100644 index 0000000000..8614ba126b --- /dev/null +++ b/hugegraph-commons/hugegraph-common/README.md @@ -0,0 +1,23 @@ +# hugegraph-common + +[![License](https://img.shields.io/badge/license-Apache%202-0E78BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) +[![Build Status](https://travis-ci.org/hugegraph/hugegraph-common.svg?branch=master)](https://travis-ci.org/hugegraph/hugegraph-common) +[![codecov](https://codecov.io/gh/hugegraph/hugegraph-common/branch/master/graph/badge.svg)](https://codecov.io/gh/hugegraph/hugegraph-common) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.hugegraph/hugegraph-common/badge.svg)](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. diff --git a/hugegraph-commons/hugegraph-common/build.sh b/hugegraph-commons/hugegraph-common/build.sh new file mode 100644 index 0000000000..b2cb6211b9 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/build.sh @@ -0,0 +1,23 @@ +#!/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 diff --git a/hugegraph-commons/hugegraph-common/pom.xml b/hugegraph-commons/hugegraph-common/pom.xml new file mode 100644 index 0000000000..4c84b30c99 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/pom.xml @@ -0,0 +1,298 @@ + + + + 4.0.0 + + org.apache.hugegraph + hugegraph-commons + ${revision} + ../pom.xml + + + hugegraph-common + ${project.artifactId} + https://github.com/apache/incubator-hugegraph-commons/tree/master/hugegraph-common + + 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. + + + + + 4.10.0 + + + + + + junit + junit + ${junit.version} + + + org.mockito + mockito-core + ${mockito.version} + test + + + + + org.apache.logging.log4j + log4j-api + ${log4j2.version} + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4j2.version} + + + + + org.glassfish + javax.json + ${javax.json.version} + + + commons-configuration + commons-configuration + ${commons.configuration.version} + + + org.apache.commons + commons-configuration2 + ${commons.configuration2.version} + + + commons-logging + commons-logging + + + commons-lang3 + org.apache.commons + + + + + org.apache.commons + commons-lang3 + ${commons.lang3.version} + + + commons-beanutils + commons-beanutils + ${commons.beanutils.version} + + + commons-logging + commons-logging + + + + + commons-io + commons-io + ${commons.io.version} + + + commons-collections + commons-collections + ${commons.collections.version} + + + commons-codec + commons-codec + ${commons.codec.version} + + + com.google.guava + guava + ${guava.version} + + + jsr305 + com.google.code.findbugs + + + + + + com.google.code.findbugs + jsr305 + ${jsr305.version} + + + + joda-time + joda-time + 2.10.8 + + + + + org.javassist + javassist + ${javassist.version} + + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + ${jackson.version} + + + jakarta.xml.bind-api + jakarta.xml.bind + + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base + ${jackson.version} + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + ${jackson.version} + + + + com.sun.xml.bind + jaxb-impl + ${sun.xml.version} + runtime + + + jakarta.xml.bind-api + jakarta.xml.bind + + + + + + com.squareup.okhttp3 + okhttp + + + com.squareup.okhttp3 + logging-interceptor + + + org.projectlombok + lombok + + + + + + + com.squareup.okhttp3 + okhttp-bom + ${okhttp.version} + pom + import + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.jacoco + jacoco-maven-plugin + 0.8.2 + + + pre-unit-test + + prepare-agent + + + + post-unit-test + test + + report + + + ${project.parent.build.directory} + + + + + + + + + + apache-release + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-gpg-plugin + + + + + + diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/AtomicLock.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/AtomicLock.java new file mode 100644 index 0000000000..6f7a669d7d --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/AtomicLock.java @@ -0,0 +1,82 @@ +/* + * 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 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/BarrierEvent.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/BarrierEvent.java new file mode 100644 index 0000000000..3c8734d16d --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/BarrierEvent.java @@ -0,0 +1,104 @@ +/* + * 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(); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/KeyLock.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/KeyLock.java new file mode 100644 index 0000000000..44ca8803ca --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/KeyLock.java @@ -0,0 +1,144 @@ +/* + * 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 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 lockAll(Object... keys) { + E.checkArgument(keys != null && keys.length > 0, + "Lock keys can't be null or empty"); + List 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 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 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 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(); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/LockGroup.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/LockGroup.java new file mode 100644 index 0000000000..aa864ecaf8 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/LockGroup.java @@ -0,0 +1,85 @@ +/* + * 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 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 > RowLock rowLock(String lockName) { + if (!this.locksMap.containsKey(lockName)) { + this.locksMap.putIfAbsent(lockName, new RowLock<>()); + } + Object value = this.locksMap.get(lockName); + @SuppressWarnings("unchecked") + RowLock lock = (RowLock) value; + return lock; + } + + public String name() { + return this.name; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/LockManager.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/LockManager.java new file mode 100644 index 0000000000..e686c67895 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/LockManager.java @@ -0,0 +1,71 @@ +/* + * 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 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)); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/PausableScheduledThreadPool.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/PausableScheduledThreadPool.java new file mode 100644 index 0000000000..a820aeb638 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/PausableScheduledThreadPool.java @@ -0,0 +1,78 @@ +/* + * 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 shutdownNow() { + if (this.paused) { + this.resumeSchedule(); + } + return super.shutdownNow(); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/RowLock.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/RowLock.java new file mode 100644 index 0000000000..3908803771 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/concurrent/RowLock.java @@ -0,0 +1,98 @@ +/* + * 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> { + + private final Map locks = new ConcurrentHashMap<>(); + private final ThreadLocal> 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 keys) { + E.checkArgument(keys != null && keys.size() > 0, + "Lock keys can't be null or empty"); + List list = new ArrayList<>(keys); + Collections.sort(list); + for (K key : list) { + this.lock(key); + } + } + + public void unlockAll(Set 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; + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigConvOption.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigConvOption.java new file mode 100644 index 0000000000..bb794ec48b --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigConvOption.java @@ -0,0 +1,47 @@ +/* + * 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 extends TypedOption { + + private final Function converter; + + public ConfigConvOption(String name, String desc, Predicate pred, + Function convert, T value) { + this(name, false, desc, pred, convert, value); + } + + @SuppressWarnings("unchecked") + public ConfigConvOption(String name, boolean required, String desc, + Predicate pred, Function convert, + T value) { + super(name, required, desc, pred, (Class) value.getClass(), value); + E.checkNotNull(convert, "convert"); + this.converter = convert; + } + + @Override + public R convert(T value) { + return this.converter.apply(value); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigException.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigException.java new file mode 100644 index 0000000000..51ba0c2f55 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigException.java @@ -0,0 +1,39 @@ +/* + * 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); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigListConvOption.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigListConvOption.java new file mode 100644 index 0000000000..79996c3680 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigListConvOption.java @@ -0,0 +1,75 @@ +/* + * 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 extends TypedOption, List> { + + private final Class elemClass; + private final Function converter; + + @SuppressWarnings("unchecked") + public ConfigListConvOption(String name, String desc, + Predicate> pred, Function convert, + T... values) { + this(name, false, desc, pred, convert, null, Arrays.asList(values)); + } + + @SuppressWarnings("unchecked") + public ConfigListConvOption(String name, boolean required, String desc, + Predicate> pred, Function convert, + Class clazz, List values) { + super(name, required, desc, pred, + (Class>) values.getClass(), values); + E.checkNotNull(convert, "convert"); + if (clazz == null && values.size() > 0) { + clazz = (Class) 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 parse(String value) { + return ConfigListOption.convert(value, part -> { + return this.parse(part, this.elemClass); + }); + } + + @Override + public List convert(List values) { + List results = new ArrayList<>(values.size()); + for (T value : values) { + results.add(this.converter.apply(value)); + } + return results; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigListOption.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigListOption.java new file mode 100644 index 0000000000..0a41e3b7e4 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigListOption.java @@ -0,0 +1,79 @@ +/* + * 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 extends ConfigOption> { + + private final Class elemClass; + + @SuppressWarnings("unchecked") + public ConfigListOption(String name, String desc, + Predicate> pred, T... values) { + this(name, false, desc, pred, null, Arrays.asList(values)); + } + + @SuppressWarnings("unchecked") + public ConfigListOption(String name, boolean required, String desc, + Predicate> pred, Class clazz, + List values) { + super(name, required, desc, pred, + (Class>) values.getClass(), values); + if (clazz == null && values.size() > 0) { + clazz = (Class) 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 parse(String value) { + return convert(value, part -> this.parse(part, this.elemClass)); + } + + @SuppressWarnings("unchecked") + public static List convert(Object value, Function conv) { + if (value instanceof List) { + return (List) 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 results = new ArrayList<>(parts.length); + for (String part : parts) { + results.add((T) conv.apply(part.trim())); + } + return results; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigOption.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigOption.java new file mode 100644 index 0000000000..159f13901f --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/ConfigOption.java @@ -0,0 +1,37 @@ +/* + * 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 extends TypedOption { + + public ConfigOption(String name, String desc, T value) { + this(name, desc, null, value); + } + + @SuppressWarnings("unchecked") + public ConfigOption(String name, String desc, Predicate pred, T value) { + this(name, false, desc, pred, (Class) value.getClass(), value); + } + + public ConfigOption(String name, boolean required, String desc, + Predicate pred, Class type, T value) { + super(name, required, desc, pred, type, value); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/HugeConfig.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/HugeConfig.java new file mode 100644 index 0000000000..4837154563 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/HugeConfig.java @@ -0,0 +1,216 @@ +/* + * 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 propertyMap) { + if (propertyMap == null) { + throw new ConfigException("The property map is null"); + } + + for (Map.Entry 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 R get(TypedOption option) { + Object value = this.getProperty(option.name()); + if (value == null) { + return option.defaultValue(); + } + return (R) value; + } + + public Map getMap(ConfigListOption option) { + List values = this.get(option); + Map 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 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); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/OptionChecker.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/OptionChecker.java new file mode 100644 index 0000000000..77364e1789 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/OptionChecker.java @@ -0,0 +1,83 @@ +/* + * 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 Predicate 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 Predicate allowValues(O... values) { + return o -> o != null && Arrays.asList(values).contains(o); + } + + @SuppressWarnings("unchecked") + public static Predicate> inValues(O... values) { + return o -> o != null && new HashSet<>(Arrays.asList(values)).containsAll(o); + } + + public static Predicate positiveInt() { + return number -> number != null && number.longValue() > 0; + } + + public static Predicate nonNegativeInt() { + return number -> number != null && number.longValue() >= 0; + } + + public static Predicate 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 Predicate rangeDouble(N min, N max) { + return number -> { + if (number == null) { + return false; + } + double value = number.doubleValue(); + return value >= min.doubleValue() && value <= max.doubleValue(); + }; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/OptionHolder.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/OptionHolder.java new file mode 100644 index 0000000000..8f4ddca764 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/OptionHolder.java @@ -0,0 +1,59 @@ +/* + * 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> 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> options() { + return Collections.unmodifiableMap(this.options); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/OptionSpace.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/OptionSpace.java new file mode 100644 index 0000000000..7193d23deb --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/OptionSpace.java @@ -0,0 +1,120 @@ +/* + * 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> HOLDERS; + private static final Map> 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 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); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/TypedOption.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/TypedOption.java new file mode 100644 index 0000000000..fc2c7de2ff --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/config/TypedOption.java @@ -0,0 +1,194 @@ +/* + * 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 { + + private static final Logger LOG = Log.logger(TypedOption.class); + + private static final Set> 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 dataType; + private final T defaultValue; + private final Predicate checkFunc; + + @SuppressWarnings("unchecked") + public TypedOption(String name, boolean required, String desc, + Predicate pred, Class type, T value) { + E.checkNotNull(name, "name"); + E.checkNotNull(type, "dataType"); + + this.name = name; + this.dataType = (Class) this.checkAndAssignDataType(type); + this.defaultValue = value; + this.required = required; + this.desc = desc; + this.checkFunc = pred; + + this.check(this.defaultValue); + } + + private Class checkAndAssignDataType(Class 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 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); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/date/SafeDateFormat.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/date/SafeDateFormat.java new file mode 100644 index 0000000000..716880568a --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/date/SafeDateFormat.java @@ -0,0 +1,64 @@ +/* + * 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/event/Event.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/event/Event.java new file mode 100644 index 0000000000..b9cf87fa76 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/event/Event.java @@ -0,0 +1,71 @@ +/* + * 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)); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/event/EventHub.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/event/EventHub.java new file mode 100644 index 0000000000..b37c67133b --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/event/EventHub.java @@ -0,0 +1,197 @@ +/* + * 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 EMPTY = ImmutableList.of(); + + // Event executor + private static ExecutorService executor = null; + + private String name; + private Map> 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 ls = this.listeners.get(event); + return ls != null && ls.size() > 0; + } + + public List listeners(String event) { + List 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 ls = this.listeners.get(event); + assert ls != null : this.listeners; + ls.add(listener); + } + + public List unlisten(String event) { + List ls = this.listeners.remove(event); + return ls == null ? EMPTY : Collections.unmodifiableList(ls); + } + + public int unlisten(String event, EventListener listener) { + List ls = this.listeners.get(event); + if (ls == null) { + return 0; + } + + int count = 0; + while (ls.remove(listener)) { + count++; + } + return count; + } + + public Future notify(String event, @Nullable Object... args) { + @SuppressWarnings("resource") + ExtendableIterator all = new ExtendableIterator<>(); + + List ls = this.listeners.get(event); + if (ls != null && !ls.isEmpty()) { + all.extend(ls.iterator()); + } + List 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 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)); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/event/EventListener.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/event/EventListener.java new file mode 100644 index 0000000000..24fc594a5b --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/event/EventListener.java @@ -0,0 +1,27 @@ +/* + * 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); +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/func/TriFunction.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/func/TriFunction.java new file mode 100644 index 0000000000..4b086440bc --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/func/TriFunction.java @@ -0,0 +1,23 @@ +/* + * 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 { + + R apply(T1 v1, T2 v2, T3 v3); +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/BatchMapperIterator.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/BatchMapperIterator.java new file mode 100644 index 0000000000..795ba61f93 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/BatchMapperIterator.java @@ -0,0 +1,104 @@ +/* + * 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 extends WrappedIterator { + + private final int batch; + private final Iterator originIterator; + private final Function, Iterator> mapperCallback; + + private Iterator batchIterator; + + public BatchMapperIterator(int batch, Iterator origin, + Function, Iterator> 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 originIterator() { + return this.originIterator; + } + + @Override + protected final boolean fetch() { + if (this.batchIterator != null && this.fetchFromBatch()) { + return true; + } + + List 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 nextBatch() { + if (!this.originIterator.hasNext()) { + return ImmutableList.of(); + } + List 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/CIter.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/CIter.java new file mode 100644 index 0000000000..249d8dc8e4 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/CIter.java @@ -0,0 +1,23 @@ +/* + * 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 extends Iterator, AutoCloseable, Metadatable { +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/ExtendableIterator.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/ExtendableIterator.java new file mode 100644 index 0000000000..b692ad361d --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/ExtendableIterator.java @@ -0,0 +1,109 @@ +/* + * 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 com.google.common.base.Preconditions; + +import org.apache.hugegraph.util.E; + +public class ExtendableIterator extends WrappedIterator { + + private final Deque> itors; + + private Iterator currentIterator; + + public ExtendableIterator() { + this.itors = new ConcurrentLinkedDeque<>(); + this.currentIterator = null; + } + + public ExtendableIterator(Iterator iter) { + this(); + this.extend(iter); + } + + public ExtendableIterator(Iterator itor1, Iterator itor2) { + this(); + this.extend(itor1); + this.extend(itor2); + } + + public ExtendableIterator extend(Iterator iter) { + E.checkState(this.currentIterator == null, + "Can't extend iterator after iterating"); + if (iter != null) { + this.itors.addLast(iter); + } + return this; + } + + public static ExtendableIterator concat(Iterator lhs, Iterator rhs) { + Preconditions.checkNotNull(lhs); + Preconditions.checkNotNull(rhs); + if (lhs instanceof ExtendableIterator) { + return ((ExtendableIterator) lhs).extend(rhs); + } + return new ExtendableIterator<>(lhs, rhs); + } + + @Override + public void close() throws Exception { + for (Iterator iter : this.itors) { + if (iter instanceof AutoCloseable) { + ((AutoCloseable) iter).close(); + } + } + } + + @Override + protected Iterator 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 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/FilterIterator.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/FilterIterator.java new file mode 100644 index 0000000000..d467f5151a --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/FilterIterator.java @@ -0,0 +1,51 @@ +/* + * 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 extends WrappedIterator { + + private final Iterator originIterator; + private final Function filterCallback; + + public FilterIterator(Iterator origin, Function filter) { + this.originIterator = origin; + this.filterCallback = filter; + } + + @Override + protected Iterator 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/FlatMapperFilterIterator.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/FlatMapperFilterIterator.java new file mode 100644 index 0000000000..e202a1dffe --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/FlatMapperFilterIterator.java @@ -0,0 +1,50 @@ +/* + * 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 extends FlatMapperIterator { + + private final Function filterCallback; + + public FlatMapperFilterIterator(Iterator origin, + Function> mapper, + Function 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/FlatMapperIterator.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/FlatMapperIterator.java new file mode 100644 index 0000000000..3273ab8ec8 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/FlatMapperIterator.java @@ -0,0 +1,89 @@ +/* + * 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 extends WrappedIterator { + + private final Iterator originIterator; + private final Function> mapperCallback; + + protected Iterator batchIterator; + + public FlatMapperIterator(Iterator origin, + Function> mapper) { + this.originIterator = origin; + this.mapperCallback = mapper; + this.batchIterator = null; + } + + @Override + public void close() throws Exception { + this.resetBatchIterator(); + super.close(); + } + + @Override + protected Iterator 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/LimitIterator.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/LimitIterator.java new file mode 100644 index 0000000000..9df6299a6b --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/LimitIterator.java @@ -0,0 +1,64 @@ +/* + * 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 extends WrappedIterator { + + private final Iterator originIterator; + private final Function filterCallback; + + public LimitIterator(Iterator origin, Function filter) { + this.originIterator = origin; + this.filterCallback = filter; + } + + @Override + protected Iterator 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); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/ListIterator.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/ListIterator.java new file mode 100644 index 0000000000..77d54765fd --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/ListIterator.java @@ -0,0 +1,78 @@ +/* + * 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 extends WrappedIterator { + + private final Iterator originIterator; + private final Iterator resultsIterator; + private final Collection results; + + public ListIterator(long capacity, Iterator origin) { + List 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 origin) { + this.originIterator = origin.iterator(); + this.results = origin instanceof List ? + Collections.unmodifiableList((List) origin) : + Collections.unmodifiableCollection(origin); + this.resultsIterator = this.results.iterator(); + } + + @Override + public void remove() { + this.resultsIterator.remove(); + } + + public Collection 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 originIterator() { + return this.originIterator; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/MapperIterator.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/MapperIterator.java new file mode 100644 index 0000000000..f93d4ab5d3 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/MapperIterator.java @@ -0,0 +1,51 @@ +/* + * 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 extends WrappedIterator { + + private final Iterator originIterator; + private final Function mapperCallback; + + public MapperIterator(Iterator origin, Function mapper) { + this.originIterator = origin; + this.mapperCallback = mapper; + } + + @Override + protected Iterator 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/Metadatable.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/Metadatable.java new file mode 100644 index 0000000000..992138ab53 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/Metadatable.java @@ -0,0 +1,23 @@ +/* + * 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); +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/WrappedIterator.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/WrappedIterator.java new file mode 100644 index 0000000000..9836d997c7 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/iterator/WrappedIterator.java @@ -0,0 +1,99 @@ +/* + * 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 implements CIter { + + 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 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(); +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseCommonParam.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseCommonParam.java new file mode 100644 index 0000000000..dac13e8d1a --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseCommonParam.java @@ -0,0 +1,106 @@ +/* + * 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 extraParams; + + public LicenseCommonParam() { + // pass + } + + public LicenseCommonParam(String subject, String description, + Date issued, Date notBefore, Date notAfter, + String consumerType, int consumerAmount, + List 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 extraParams() { + return this.extraParams; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseCreateParam.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseCreateParam.java new file mode 100644 index 0000000000..d67f8a2a3d --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseCreateParam.java @@ -0,0 +1,61 @@ +/* + * 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseExtraParam.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseExtraParam.java new file mode 100644 index 0000000000..4f563ebce2 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseExtraParam.java @@ -0,0 +1,119 @@ +/* + * 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseInstallParam.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseInstallParam.java new file mode 100644 index 0000000000..3717e5d518 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseInstallParam.java @@ -0,0 +1,60 @@ +/* + * 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseManager.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseManager.java new file mode 100644 index 0000000000..47bb886b07 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseManager.java @@ -0,0 +1,32 @@ +/* + * 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseManagerFactory.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseManagerFactory.java new file mode 100644 index 0000000000..5794663175 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseManagerFactory.java @@ -0,0 +1,30 @@ +/* + * 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"); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseParams.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseParams.java new file mode 100644 index 0000000000..94b9dd15c0 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/LicenseParams.java @@ -0,0 +1,45 @@ +/* + * 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 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; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/MachineInfo.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/MachineInfo.java new file mode 100755 index 0000000000..cd106921ea --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/license/MachineInfo.java @@ -0,0 +1,126 @@ +/* + * 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 ipAddressList; + private List macAddressList; + + public MachineInfo() { + this.ipAddressList = null; + this.macAddressList = null; + } + + public List getIpAddress() { + if (this.ipAddressList != null) { + return this.ipAddressList; + } + this.ipAddressList = new ArrayList<>(); + List 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 getMacAddress() { + if (this.macAddressList != null) { + return this.macAddressList; + } + this.macAddressList = new ArrayList<>(); + List inetAddresses = this.getLocalAllInetAddress(); + if (inetAddresses != null && !inetAddresses.isEmpty()) { + // Get the Mac address of all network interfaces + List list = new ArrayList<>(); + Set 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 getLocalAllInetAddress() { + Enumeration interfaces; + try { + interfaces = NetworkInterface.getNetworkInterfaces(); + } catch (SocketException e) { + throw new RuntimeException("Failed to get network interfaces"); + } + + List result = new ArrayList<>(); + while (interfaces.hasMoreElements()) { + NetworkInterface nw = interfaces.nextElement(); + for (Enumeration 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(); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/LightStopwatch.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/LightStopwatch.java new file mode 100644 index 0000000000..6bdbcaad37 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/LightStopwatch.java @@ -0,0 +1,185 @@ +/* + * 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 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 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); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/NormalStopwatch.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/NormalStopwatch.java new file mode 100644 index 0000000000..40901434e8 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/NormalStopwatch.java @@ -0,0 +1,302 @@ +/* + * 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 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 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 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 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); + } + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/PerfUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/PerfUtil.java new file mode 100644 index 0000000000..77b68d6be7 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/PerfUtil.java @@ -0,0 +1,687 @@ +/* + * 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 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 stopwatches; + private final LocalStack 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 loadedClasses = new HashSet<>(); + + Function inPackage = (cls) -> { + for (String pkg : packages) { + if (cls.startsWith(pkg)) { + return true; + } + } + return false; + }; + + ThrowableConsumer 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 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 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 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, 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> fillChildrenTotal = + (itemsOfLn, itemsOfLnParent) -> { + for (Stopwatch parent : itemsOfLnParent) { + List children = itemsOfLn.stream().filter(c -> { + return c.parent().equals(parent.id()); + }).collect(Collectors.toList()); + + parent.fillChildrenTotal(children); + } + }; + + BiConsumer, List> fillOther = + (itemsOfLn, itemsOfLnParent) -> { + for (Stopwatch parent : itemsOfLnParent) { + Stream 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 items = this.stopwatches; + Map> levelItems = new HashMap<>(); + int maxDepth = 0; + for (Map.Entry e : items.entrySet()) { + int depth = e.getKey().toString().split("/").length; + List 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 itemsOfI = levelItems.get(i); + List 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 + '%
'" + + " + 'cost: ' + params.data.cost + ' (ms)
'" + + " + 'min cost: ' + params.data.minCost + ' (ns)
'" + + " + 'max cost: ' + params.data.maxCost + ' (ns)
'" + + " + 'wasted: ' + params.data.wasted + ' (ms)
'" + + " + 'self wasted: ' + params.data.selfWasted + ' (ms)
'" + + " + 'times: ' + params.data.times + '
'" + + " + 'total times: ' + params.data.totalTimes + '
'" + + " + 'path: ' + params.data.id + '
';" + + "}"); + sb.append("},"); + sb.append("series: ["); + // Output results data + for (int i = 1; i <= maxDepth; i++) { + assert levelItems.containsKey(i) : i; + List itemsOfI = levelItems.get(i); + List 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 { + + 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 { + + private final Map 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 ""; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/Stopwatch.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/Stopwatch.java new file mode 100644 index 0000000000..487c778820 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/perf/Stopwatch.java @@ -0,0 +1,148 @@ +/* + * 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 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 { + + 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); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/AbstractRestClient.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/AbstractRestClient.java new file mode 100644 index 0000000000..c13a686b71 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/AbstractRestClient.java @@ -0,0 +1,490 @@ +/* + * 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 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 params) { + return this.post(path, object, null, params); + } + + private Request.Builder genRequestBuilder(String path, String id, RestHeaders headers, + Map 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 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 params) { + return this.put(path, id, object, null, params); + } + + @SneakyThrows + @Override + public RestResult put(String path, String id, Object object, + RestHeaders headers, + Map 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 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 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 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 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); + } + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/ClientException.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/ClientException.java new file mode 100644 index 0000000000..ba954a28ff --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/ClientException.java @@ -0,0 +1,35 @@ +/* + * 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); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/OkHttpBasicAuthInterceptor.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/OkHttpBasicAuthInterceptor.java new file mode 100644 index 0000000000..f7b1509f50 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/OkHttpBasicAuthInterceptor.java @@ -0,0 +1,47 @@ +/* + * 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.IOException; + +import okhttp3.Credentials; +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +public class OkHttpBasicAuthInterceptor implements Interceptor { + + private final String credentials; + + public OkHttpBasicAuthInterceptor(String user, String password) { + this.credentials = Credentials.basic(user, password); + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + if (request.header(RestHeaders.AUTHORIZATION) == null) { + Request authenticatedRequest = request.newBuilder() + .header(RestHeaders.AUTHORIZATION, + this.credentials) + .build(); + return chain.proceed(authenticatedRequest); + } + return chain.proceed(request); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/OkHttpTokenInterceptor.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/OkHttpTokenInterceptor.java new file mode 100644 index 0000000000..f564033225 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/OkHttpTokenInterceptor.java @@ -0,0 +1,50 @@ +/* + * 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 static org.apache.hugegraph.rest.RestHeaders.AUTHORIZATION; +import static org.apache.hugegraph.rest.RestHeaders.BEARER_PREFIX; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + + +public class OkHttpTokenInterceptor implements Interceptor { + + private final String token; + + public OkHttpTokenInterceptor(String token) { + this.token = token; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + if (request.header(AUTHORIZATION) == null) { + Request authenticatedRequest = request.newBuilder() + .header(AUTHORIZATION, + BEARER_PREFIX + this.token) + .build(); + return chain.proceed(authenticatedRequest); + } + return chain.proceed(request); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestClient.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestClient.java new file mode 100644 index 0000000000..d5b58d9fc6 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestClient.java @@ -0,0 +1,63 @@ +/* + * 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.util.Map; + +public interface RestClient { + /** + * Post method + */ + RestResult post(String path, Object object); + + RestResult post(String path, Object object, RestHeaders headers); + + RestResult post(String path, Object object, Map params); + + RestResult post(String path, Object object, RestHeaders headers, Map params); + + /** + * Put method + */ + RestResult put(String path, String id, Object object); + + RestResult put(String path, String id, Object object, RestHeaders headers); + + RestResult put(String path, String id, Object object, Map params); + + RestResult put(String path, String id, Object object, RestHeaders headers, + Map params); + + /** + * Get method + */ + RestResult get(String path); + + RestResult get(String path, Map params); + + RestResult get(String path, String id); + + /** + * Delete method + */ + RestResult delete(String path, Map params); + + RestResult delete(String path, String id); + + void close(); +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestClientConfig.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestClientConfig.java new file mode 100644 index 0000000000..c8e766ba7e --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestClientConfig.java @@ -0,0 +1,53 @@ +/* + * 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.util.function.Consumer; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import okhttp3.OkHttpClient; + +@Builder +@Getter +@Setter +@SuppressWarnings("unused") +public class RestClientConfig { + + private String user; + private String password; + private String token; + /** + * @deprecated use connectTimeout and readTimeout instead + */ + @Deprecated + private Integer timeout; + /** unit in milliseconds */ + private Integer connectTimeout; + /** unit in milliseconds */ + private Integer readTimeout; + private Integer maxConns; + private Integer maxConnsPerRoute; + // unit in seconds + private Integer idleTime = 30; + private Integer maxIdleConns = 5; + private String trustStoreFile; + private String trustStorePassword; + private Consumer builderCallback; +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestHeaders.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestHeaders.java new file mode 100644 index 0000000000..03c082ede3 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestHeaders.java @@ -0,0 +1,90 @@ +/* + * 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.util.Date; +import java.util.Iterator; + +import kotlin.Pair; + +public class RestHeaders { + + public static final String CONTENT_TYPE = "Content-Type"; + + public static final String CONTENT_ENCODING = "Content-Encoding"; + + public static final String AUTHORIZATION = "Authorization"; + + public static final String APPLICATION_JSON = "application/json"; + + public static final String BEARER_PREFIX = "Bearer "; + + private final okhttp3.Headers.Builder headersBuilder; + + public RestHeaders() { + this.headersBuilder = new okhttp3.Headers.Builder(); + } + + public static RestHeaders convertToRestHeaders(okhttp3.Headers headers) { + RestHeaders restHeaders = new RestHeaders(); + + if (headers != null) { + Iterator> iter = headers.iterator(); + while (iter.hasNext()) { + Pair pair = iter.next(); + restHeaders.add(pair.getFirst(), pair.getSecond()); + } + } + return restHeaders; + } + + public String get(String key) { + return this.headersBuilder.get(key); + } + + public Date getDate(String key) { + return this.headersBuilder.build().getDate(key); + } + + public RestHeaders add(String key, String value) { + this.headersBuilder.add(key, value); + return this; + } + + public RestHeaders add(String key, Date value) { + this.headersBuilder.add(key, value); + return this; + } + + @Override + public int hashCode() { + return this.toOkHttpHeader().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof RestHeaders) { + return this.toOkHttpHeader().equals(((RestHeaders) obj).toOkHttpHeader()); + } + return false; + } + + public okhttp3.Headers toOkHttpHeader() { + return this.headersBuilder.build(); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestResult.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestResult.java new file mode 100644 index 0000000000..0aa482b067 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/RestResult.java @@ -0,0 +1,114 @@ +/* + * 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.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.databind.ObjectMapper; + +import lombok.SneakyThrows; +import okhttp3.Response; + +public class RestResult { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + private final int status; + private final RestHeaders headers; + private final String content; + + public RestResult(Response response) { + this(response.code(), getResponseContent(response), + RestHeaders.convertToRestHeaders(response.headers())); + } + + public RestResult(int status, String content, RestHeaders headers) { + this.status = status; + this.headers = headers; + this.content = content; + } + + @SneakyThrows + private static String getResponseContent(Response response) { + return response.body().string(); + } + + public static void registerModule(Module module) { + MAPPER.registerModule(module); + } + + public int status() { + return this.status; + } + + public RestHeaders headers() { + return this.headers; + } + + public String content() { + return this.content; + } + + public T readObject(Class clazz) { + try { + return MAPPER.readValue(this.content, clazz); + } catch (Exception e) { + throw new SerializeException("Failed to deserialize: %s", e, this.content); + } + } + + @SuppressWarnings("deprecation") + public List readList(String key, Class clazz) { + try { + JsonNode root = MAPPER.readTree(this.content); + JsonNode element = root.get(key); + if (element == null) { + throw new SerializeException("Can't find value of the key: %s in json.", key); + } + JavaType type = MAPPER.getTypeFactory() + .constructParametrizedType(ArrayList.class, + List.class, clazz); + return MAPPER.convertValue(element, type); + } catch (IOException e) { + throw new SerializeException("Failed to deserialize %s", e, this.content); + } + } + + @SuppressWarnings("deprecation") + public List readList(Class clazz) { + JavaType type = MAPPER.getTypeFactory() + .constructParametrizedType(ArrayList.class, + List.class, clazz); + try { + return MAPPER.readValue(this.content, type); + } catch (IOException e) { + throw new SerializeException("Failed to deserialize %s", e, this.content); + } + } + + @Override + public String toString() { + return String.format("{status=%s, headers=%s, content=%s}", this.status, this.headers, + this.content); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/SerializeException.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/SerializeException.java new file mode 100644 index 0000000000..857ea9427d --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/SerializeException.java @@ -0,0 +1,35 @@ +/* + * 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 SerializeException extends ClientException { + + private static final long serialVersionUID = -4622753445618619311L; + + public SerializeException(String message, Throwable e) { + super(message, e); + } + + public SerializeException(String message, Object... args) { + super(message, args); + } + + public SerializeException(String message, Throwable e, Object... args) { + super(message, e, args); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/testutil/Assert.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/testutil/Assert.java new file mode 100644 index 0000000000..bd82eef6a9 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/testutil/Assert.java @@ -0,0 +1,164 @@ +/* + * 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.testutil; + +import java.util.function.Consumer; +import java.util.function.Function; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.CoreMatchers; +import org.hamcrest.Description; + +public class Assert extends org.junit.Assert { + + @FunctionalInterface + public interface ThrowableRunnable { + void run() throws Throwable; + } + + @FunctionalInterface + public interface ThrowableConsumer { + void accept(T t) throws Throwable; + } + + public static void assertThrows(Class clazz, + ThrowableRunnable runnable, + Consumer exceptionConsumer) { + Throwable expectedException = assertThrows(clazz, runnable); + assert expectedException != null; + exceptionConsumer.accept(expectedException); + } + + public static Throwable assertThrows(Class clazz, + ThrowableRunnable runnable) { + try { + // expect throwing here + runnable.run(); + } catch (Throwable e) { + if (!clazz.isInstance(e)) { + // exception type not matched + Assert.fail(String.format("Bad exception type %s(expected %s)", + e.getClass().getName(), clazz.getName())); + } + + return e; + } + + // no exception + Assert.fail(String.format("No exception was thrown(expected %s)", + clazz.getName())); + + // unavailable + assert false; + return null; + } + + public static void assertEquals(byte expected, Object actual) { + org.junit.Assert.assertEquals(expected, actual); + } + + public static void assertEquals(short expected, Object actual) { + org.junit.Assert.assertEquals(expected, actual); + } + + public static void assertEquals(char expected, Object actual) { + org.junit.Assert.assertEquals(expected, actual); + } + + public static void assertEquals(int expected, Object actual) { + org.junit.Assert.assertEquals(expected, actual); + } + + public static void assertEquals(long expected, Object actual) { + org.junit.Assert.assertEquals(expected, actual); + } + + public static void assertEquals(float expected, Object actual) { + org.junit.Assert.assertEquals(expected, actual); + } + + public static void assertEquals(double expected, Object actual) { + org.junit.Assert.assertEquals(expected, actual); + } + + @SuppressWarnings("deprecation") + public static void assertGt(Number expected, Object actual) { + org.junit.Assert.assertThat(actual, new NumberMatcher(expected, cmp -> { + return cmp > 0; + }, ">")); + } + + @SuppressWarnings("deprecation") + public static void assertGte(Number expected, Object actual) { + org.junit.Assert.assertThat(actual, new NumberMatcher(expected, cmp -> { + return cmp >= 0; + }, ">=")); + } + + @SuppressWarnings("deprecation") + public static void assertLt(Number expected, Object actual) { + org.junit.Assert.assertThat(actual, new NumberMatcher(expected, cmp -> { + return cmp < 0; + }, "<")); + } + + @SuppressWarnings("deprecation") + public static void assertLte(Number expected, Object actual) { + org.junit.Assert.assertThat(actual, new NumberMatcher(expected, cmp -> { + return cmp <= 0; + }, "<=")); + } + + @SuppressWarnings("deprecation") + public static void assertContains(String sub, String actual) { + org.junit.Assert.assertThat(actual, CoreMatchers.containsString(sub)); + } + + @SuppressWarnings("deprecation") + public static void assertInstanceOf(Class clazz, Object object) { + org.junit.Assert.assertThat(object, CoreMatchers.instanceOf(clazz)); + } + + private static class NumberMatcher extends BaseMatcher { + + private final String symbol; + private final Number expected; + private final Function cmp; + + NumberMatcher(Number expected, Function cmp, String symbol) { + this.expected = expected; + this.cmp = cmp; + this.symbol = symbol; + } + + @SuppressWarnings("unchecked") + @Override + public boolean matches(Object actual) { + Assert.assertInstanceOf(this.expected.getClass(), actual); + Assert.assertInstanceOf(Comparable.class, actual); + int cmp = ((Comparable) actual).compareTo(this.expected); + return this.cmp.apply(cmp); + } + + @Override + public void describeTo(Description desc) { + desc.appendText("a number ").appendText(this.symbol) + .appendText(" ").appendText(this.expected.toString()); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/testutil/Whitebox.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/testutil/Whitebox.java new file mode 100644 index 0000000000..73d8ee2afd --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/testutil/Whitebox.java @@ -0,0 +1,184 @@ +/* + * 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.testutil; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Objects; + +import org.apache.hugegraph.util.E; +import com.google.common.primitives.Primitives; + +public class Whitebox { + + public static final char SEPARATOR = '.'; + + public static void setInternalState(Object target, + String fieldName, Object value) { + assert target != null; + assert fieldName != null; + int sep = fieldName.lastIndexOf(SEPARATOR); + if (sep > 0) { + String prefix = fieldName.substring(0, sep); + Object result = getInternalState(target, prefix); + E.checkArgument(result != null, + "Can't set value on null field: `%s.%s`", + target, prefix); + target = result; + fieldName = fieldName.substring(sep + 1); + } + + Class c = target instanceof Class ? + (Class) target : target.getClass(); + try { + Field f = getFieldFromHierarchy(c, fieldName); + f.setAccessible(true); + f.set(target, value); + } catch (Exception e) { + throw new RuntimeException(String.format( + "Can't set value of '%s' against object '%s'", + fieldName, target), e); + } + } + + public static T getInternalState(Object target, String fieldName) { + assert fieldName != null; + int sep = fieldName.indexOf(SEPARATOR); + if (sep > 0) { + String field = fieldName.substring(0, sep); + Object value = getInternalState(target, field); + field = fieldName.substring(sep + 1); + return getInternalState(value, field); + } + + Class c = target instanceof Class ? + (Class) target : target.getClass(); + try { + Field f = getFieldFromHierarchy(c, fieldName); + f.setAccessible(true); + @SuppressWarnings("unchecked") + T result = (T) f.get(target); + return result; + } catch (Exception e) { + throw new RuntimeException(String.format( + "Unable to get internal state on field '%s' of %s", + fieldName, target), e); + } + } + + private static Field getFieldFromHierarchy(Class clazz, String field) { + Field f = getField(clazz, field); + while (f == null && clazz != Object.class) { + clazz = clazz.getSuperclass(); + f = getField(clazz, field); + } + if (f == null) { + throw new RuntimeException(String.format( + "Not declared field '%s' in class '%s'", + field, clazz.getSimpleName())); + } + return f; + } + + private static Field getField(Class clazz, String field) { + try { + return clazz.getDeclaredField(field); + } catch (NoSuchFieldException e) { + return null; + } + } + + public static T invokeStatic(Class clazz, String methodName, + Object... args) { + return invoke(clazz, methodName, (Object) null, args); + } + + public static T invokeStatic(Class clazz, Class[] classes, + String methodName, Object... args) { + return invoke(clazz, classes, methodName, (Object) null, args); + } + + public static T invoke(Object owner, String field, + String methodName, Object... args) { + Object self = getInternalState(owner, field); + Objects.requireNonNull(self); + return invoke(self.getClass(), methodName, self, args); + } + + public static T invoke(Object owner, String field, Class[] classes, + String methodName, Object... args) { + Object self = getInternalState(owner, field); + Objects.requireNonNull(self); + return invoke(self.getClass(), classes, methodName, self, args); + } + + public static T invoke(Class clazz, String methodName, + Object self, Object... args) { + Class[] classes = new Class[args.length]; + int i = 0; + for (Object arg : args) { + E.checkArgument(arg != null, "The argument can't be null"); + classes[i++] = Primitives.unwrap(arg.getClass()); + } + return invoke(clazz, classes, methodName, self, args); + } + + public static T invoke(Class clazz, Class[] classes, + String methodName, Object self, Object... args) { + Method method = method(clazz, methodName, classes); + try { + method.setAccessible(true); + @SuppressWarnings("unchecked") + T result = (T) method.invoke(self, args); + return result; + } catch (IllegalAccessException e) { + throw new RuntimeException(String.format( + "Can't invoke method '%s' of class '%s': %s", + methodName, clazz, e.getMessage()), e); + } catch (InvocationTargetException e) { + Throwable target = e.getTargetException(); + if (target instanceof RuntimeException) { + throw (RuntimeException) target; + } + throw new RuntimeException(String.format( + "Can't invoke method '%s' of class '%s': %s", + methodName, clazz, target.getMessage()), target); + } + } + + public static Method method(Class clazz, String methodName, + Class[] argsClasses) { + try { + return clazz.getDeclaredMethod(methodName, argsClasses); + } catch (NoSuchMethodException e) { + Class superclass = clazz.getSuperclass(); + if (superclass != null) { + try { + return method(superclass, methodName, argsClasses); + } catch (Exception ignored) { + // pass + } + } + throw new RuntimeException(String.format( + "Can't find method '%s' with args %s of class '%s'", + methodName, Arrays.asList(argsClasses), clazz), e); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/Bytes.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/Bytes.java new file mode 100644 index 0000000000..4abd57df44 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/Bytes.java @@ -0,0 +1,103 @@ +/* + * 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.util; + +import java.util.Arrays; +import java.util.Comparator; + +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Hex; + +import com.google.common.primitives.UnsignedBytes; + +/** + * TODO: extends com.google.common.primitives.Bytes + */ +public final class Bytes { + + public static final long BASE = 1024L; + public static final long KB = BASE; + public static final long MB = KB * BASE; + public static final long GB = MB * BASE; + public static final long TB = GB * KB; + public static final long PB = GB * MB; + public static final long EB = GB * GB; + + private static final Comparator CMP = UnsignedBytes.lexicographicalComparator(); + + public static int compare(byte[] bytes1, byte[] bytes2) { + return CMP.compare(bytes1, bytes2); + } + + public static byte[] concat(byte[] bytes1, byte[] bytes2) { + byte[] result = new byte[bytes1.length + bytes2.length]; + System.arraycopy(bytes1, 0, result, 0, bytes1.length); + System.arraycopy(bytes2, 0, result, bytes1.length, bytes2.length); + return result; + } + + public static boolean prefixWith(byte[] bytes, byte[] prefix) { + if (bytes.length < prefix.length) { + return false; + } + for (int i = 0; i < prefix.length; i++) { + if (bytes[i] != prefix[i]) { + return false; + } + } + return true; + } + + public static boolean contains(byte[] bytes, byte value) { + for (byte b : bytes) { + if (b == value) { + return true; + } + } + return false; + } + + public static int indexOf(byte[] bytes, byte value) { + for (int i = 0; i < bytes.length; i++) { + if (bytes[i] == value) { + return i; + } + } + return -1; + } + + public static boolean equals(byte[] bytes1, byte[] bytes2) { + return Arrays.equals(bytes1, bytes2); + } + + public static String toHex(byte b) { + return toHex(new byte[]{b}); + } + + public static String toHex(byte[] bytes) { + return new String(Hex.encodeHex(bytes)); + } + + public static byte[] fromHex(String hex) { + try { + return Hex.decodeHex(hex.toCharArray()); + } catch (DecoderException e) { + throw new RuntimeException("Failed to decode hex: " + hex, e); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/CheckSocket.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/CheckSocket.java new file mode 100644 index 0000000000..09a36b9a36 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/CheckSocket.java @@ -0,0 +1,37 @@ +/* + * 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.util; + +import static java.lang.System.exit; + +import java.net.InetAddress; +import java.net.Socket; + +public final class CheckSocket { + + public static void main(String[] args) { + try { + // Check if the socket connection can be closed normally + new Socket(InetAddress.getByName(args[0]), Integer.parseInt(args[1])).close(); + exit(0); + } catch (Exception e) { + e.printStackTrace(); + exit(-1); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/CollectionUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/CollectionUtil.java new file mode 100644 index 0000000000..f719b8a552 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/CollectionUtil.java @@ -0,0 +1,448 @@ +/* + * 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.util; + +import java.lang.reflect.Array; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Deque; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; +import java.util.function.Function; + +public final class CollectionUtil { + + public static Set toSet(Object object) { + E.checkNotNull(object, "object"); + Set set = InsertionOrderUtil.newSet(); + fillCollection(set, object); + return set; + } + + public static List toList(Object object) { + E.checkNotNull(object, "object"); + List list = new ArrayList<>(); + fillCollection(list, object); + return list; + } + + @SuppressWarnings("unchecked") + private static void fillCollection(Collection collection, + Object object) { + if (object.getClass().isArray()) { + int length = Array.getLength(object); + for (int i = 0; i < length; i++) { + collection.add((T) Array.get(object, i)); + } + } else if (object instanceof Collection) { + collection.addAll((Collection) object); + } else { + collection.add((T) object); + } + } + + public static boolean prefixOf(List prefix, List all) { + E.checkNotNull(prefix, "prefix"); + E.checkNotNull(all, "all"); + + if (prefix.size() > all.size()) { + return false; + } + + for (int i = 0; i < prefix.size(); i++) { + T first = prefix.get(i); + T second = all.get(i); + if (first == second) { + continue; + } + if (first == null || !first.equals(second)) { + return false; + } + } + return true; + } + + public static Set randomSet(int min, int max, int count) { + E.checkArgument(max > min, "Invalid min/max: %s/%s", min, max); + E.checkArgument(0 < count && count <= max - min, + "Invalid count %s", count); + + Set randoms = new HashSet<>(); + while (randoms.size() < count) { + randoms.add(ThreadLocalRandom.current().nextInt(min, max)); + } + return randoms; + } + + public static boolean allUnique(Collection collection) { + HashSet set = new HashSet<>(collection.size()); + for (Object elem : collection) { + if (!set.add(elem)) { + return false; + } + } + return true; + } + + /** + * Get sub-set of a set. + * @param original original set + * @param from index of start position + * @param to index of end position(exclude), but -1 means the last element + * @param element type of set + * @return sub-set of original set [from, to) + */ + public static Set subSet(Set original, int from, int to) { + E.checkArgument(from >= 0, + "Invalid from parameter of subSet(): %s", from); + if (to < 0) { + to = original.size(); + } else { + E.checkArgument(to >= from, + "Invalid to parameter of subSet(): %s", to); + } + List list = new ArrayList<>(original); + return new LinkedHashSet<>(list.subList(from, to)); + } + + public static Set union(Collection first, Collection second) { + E.checkNotNull(first, "first"); + E.checkNotNull(second, "second"); + HashSet results = new HashSet<>(first); + results.addAll(second); + return results; + } + + /** + * Find the intersection of two collections, the original collections + * will not be modified + * @param first the first collection + * @param second the second collection + * @param element type of collection + * @return intersection of the two collections + */ + public static Collection intersect(Collection first, + Collection second) { + E.checkNotNull(first, "first"); + E.checkNotNull(second, "second"); + + HashSet results; + if (first instanceof HashSet) { + @SuppressWarnings("unchecked") + HashSet clone = (HashSet) ((HashSet) first).clone(); + results = clone; + } else { + results = new HashSet<>(first); + } + results.retainAll(second); + return results; + } + + /** + * Find the intersection of two collections, note that the first collection + * will be modified and store the results + * @param first the first collection, it will be modified + * @param second the second collection + * @param element type of collection + * @return intersection of the two collections + */ + public static Collection intersectWithModify(Collection first, + Collection second) { + E.checkNotNull(first, "first"); + E.checkNotNull(second, "second"); + first.retainAll(second); + return first; + } + + public static boolean hasIntersection(List first, Set second) { + E.checkNotNull(first, "first"); + E.checkNotNull(second, "second"); + for (T firstElem : first) { + if (second.contains(firstElem)) { + return true; + } + } + return false; + } + + public static boolean hasIntersection(Set first, Set second) { + E.checkNotNull(first, "first"); + E.checkNotNull(second, "second"); + if (first.size() <= second.size()) { + for (T firstElem : first) { + if (second.contains(firstElem)) { + return true; + } + } + } else { + for (T secondElem : second) { + if (first.contains(secondElem)) { + return true; + } + } + } + return false; + } + + public static , V> Map sortByKey( + Map map, boolean incr) { + List> list = new ArrayList<>(map.entrySet()); + if (incr) { + list.sort(Map.Entry.comparingByKey()); + } else { + list.sort(Collections.reverseOrder(Map.Entry.comparingByKey())); + } + + Map result = new LinkedHashMap<>(); + for (Map.Entry entry : list) { + result.put(entry.getKey(), entry.getValue()); + } + return result; + } + + public static > Map sortByValue( + Map map, boolean incr) { + List> list = new ArrayList<>(map.entrySet()); + if (incr) { + list.sort(Map.Entry.comparingByValue()); + } else { + list.sort(Collections.reverseOrder(Map.Entry.comparingByValue())); + } + + Map result = new LinkedHashMap<>(); + for (Map.Entry entry : list) { + result.put(entry.getKey(), entry.getValue()); + } + return result; + } + + /** + * Cross combine the A(n, n) combinations of each part in parts + * @param parts a list of part, like [{a,b}, {1,2}, {x,y}] + * @return List> all combinations like + * [{a,b,1,2,x,y}, {a,b,1,2,y,x}, {a,b,2,1,x,y}, {a,b,2,1,y,x}...] + */ + public static List> crossCombineParts(List> parts) { + List> results = new ArrayList<>(); + Deque> selected = new ArrayDeque<>(); + crossCombineParts(parts, 0, selected, results); + return results; + } + + private static void crossCombineParts(List> parts, + int level, + Deque> selected, + List> results) { + assert level < parts.size(); + List part = parts.get(level); + for (List combination : anm(part)) { + selected.addLast(combination); + + if (level < parts.size() - 1) { + crossCombineParts(parts, level + 1, selected, results); + } else if (level == parts.size() - 1) { + results.add(flatToList(selected)); + } + + selected.removeLast(); + } + } + + private static List flatToList(Deque> parts) { + List list = new ArrayList<>(); + for (List part : parts) { + list.addAll(part); + } + return list; + } + + /** + * Traverse C(n, m) combinations of a list + * @param all list to contain all items for combination + * @param n m of C(n, m) + * @param m n of C(n, m) + * @return List> all combinations + */ + public static List> cnm(List all, int n, int m) { + List> combs = new ArrayList<>(); + cnm(all, n, m, comb -> { + combs.add(comb); + return false; + }); + return combs; + } + + /** + * Traverse C(n, m) combinations of a list to find first matched + * result combination and call back with the result. + * @param all list to contain all items for combination + * @param n m of C(n, m) + * @param m n of C(n, m) + * @return true if matched any kind of items combination else false, the + * callback can always return false if you want to traverse all combinations + */ + public static boolean cnm(List all, int n, int m, + Function, Boolean> callback) { + return cnm(all, n, m, 0, null, callback); + } + + /** + * Traverse C(n, m) combinations of a list to find first matched + * result combination and call back with the result. + * @param all list to contain all items for combination + * @param n n of C(n, m) + * @param m m of C(n, m) + * @param current current position in list + * @param selected list to contain selected items + * @return true if matched any kind of items combination else false, the + * callback can always return false if you want to traverse all combinations + */ + private static boolean cnm(List all, int n, int m, + int current, List selected, + Function, Boolean> callback) { + assert n <= all.size(); + assert m <= n; + assert current <= all.size(); + if (selected == null) { + selected = new ArrayList<>(m); + } + + if (m == 0) { + assert selected.size() > 0 : selected; + // All n items are selected + List tmpResult = Collections.unmodifiableList(selected); + return callback.apply(tmpResult); + } + if (n == m) { + // No choice, select all n items, we don't update the `result` here + List tmpResult = new ArrayList<>(selected); + tmpResult.addAll(all.subList(current, all.size())); + return callback.apply(tmpResult); + } + + if (current >= all.size()) { + // Reach the end of items + return false; + } + + // Select current item, continue to select C(m-1, n-1) + int index = selected.size(); + selected.add(all.get(current)); + ++current; + if (cnm(all, n - 1, m - 1, current, selected, callback)) { + // NOTE: we can pop the tailing items if want to keep result clear + return true; + } + // Not select current item, pop it and continue to select C(m-1, n) + selected.remove(index); + assert selected.size() == index : selected; + return cnm(all, n - 1, m, current, selected, callback); + } + + /** + * Traverse A(n, m) combinations of a list with n = m = all.size() + * @param all list to contain all items for combination + * @return List> all combinations + */ + public static List> anm(List all) { + return anm(all, all.size(), all.size()); + } + + /** + * Traverse A(n, m) combinations of a list + * @param all list to contain all items for combination + * @param n m of A(n, m) + * @param m n of A(n, m) + * @return List> all combinations + */ + public static List> anm(List all, int n, int m) { + List> combs = new ArrayList<>(); + anm(all, n, m, comb -> { + combs.add(comb); + return false; + }); + return combs; + } + + /** + * Traverse A(n, m) combinations of a list to find first matched + * result combination and call back with the result. + * @param all list to contain all items for combination + * @param n m of A(n, m) + * @param m n of A(n, m) + * @return true if matched any kind of items combination else false, the + * callback can always return false if you want to traverse all combinations + */ + public static boolean anm(List all, int n, int m, + Function, Boolean> callback) { + return anm(all, n, m, null, callback); + } + + /** + * Traverse A(n, m) combinations of a list to find first matched + * result combination and call back with the result. + * @param all list to contain all items for combination + * @param n m of A(n, m) + * @param m n of A(n, m) + * @param selected list to contain selected items + * @return true if matched any kind of items combination else false, the + * callback can always return false if you want to traverse all combinations + */ + private static boolean anm(List all, int n, int m, + List selected, + Function, Boolean> callback) { + assert n <= all.size(); + assert m <= n; + if (selected == null) { + selected = new ArrayList<>(m); + } + + if (m == 0) { + // All n items are selected + List tmpResult = new ArrayList<>(); + for (int i : selected) { + tmpResult.add(all.get(i)); + } + return callback.apply(tmpResult); + } + + for (int i = 0; i < all.size(); i++) { + if (selected.contains(i)) { + continue; + } + int index = selected.size(); + selected.add(i); + + // Select current item, continue to select A(m-1, n-1) + if (anm(all, n - 1, m - 1, selected, callback)) { + return true; + } + + selected.remove(index); + assert selected.size() == index : selected; + } + return false; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/DateUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/DateUtil.java new file mode 100644 index 0000000000..4e7ce13de0 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/DateUtil.java @@ -0,0 +1,77 @@ +/* + * 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.util; + +import java.util.Date; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.hugegraph.date.SafeDateFormat; +import com.google.common.collect.ImmutableMap; + +public final class DateUtil { + + public static final Date DATE_ZERO = new Date(0L); + + private static final Map VALID_DFS = ImmutableMap.of( + "^\\d{4}-\\d{1,2}-\\d{1,2}", + "yyyy-MM-dd", + "^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}", + "yyyy-MM-dd HH:mm:ss", + "^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}\\.\\d{1,3}", + "yyyy-MM-dd HH:mm:ss.SSS" + ); + + private static final Map DATE_FORMATS = new ConcurrentHashMap<>(); + + public static Date parse(String value) { + for (Map.Entry entry : VALID_DFS.entrySet()) { + if (value.matches(entry.getKey())) { + return parse(value, entry.getValue()); + } + } + throw new IllegalArgumentException(String.format( + "Expected date format is: %s, but got '%s'", VALID_DFS.values(), value)); + } + + public static Date parse(String value, String df) { + SafeDateFormat dateFormat = getDateFormat(df); + return dateFormat.parse(value); + } + + public static Date now() { + return new Date(); + } + + private static SafeDateFormat getDateFormat(String df) { + SafeDateFormat dateFormat = DATE_FORMATS.get(df); + if (dateFormat == null) { + dateFormat = new SafeDateFormat(df); + SafeDateFormat previous = DATE_FORMATS.putIfAbsent(df, dateFormat); + if (previous != null) { + dateFormat = previous; + } + } + return dateFormat; + } + + public static Object toPattern(String df) { + SafeDateFormat dateFormat = getDateFormat(df); + return dateFormat.toPattern(); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/E.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/E.java new file mode 100644 index 0000000000..214add304b --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/E.java @@ -0,0 +1,66 @@ +/* + * 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.util; + +import java.util.Collection; + +import javax.annotation.Nullable; + +import com.google.common.base.Preconditions; + +public final class E { + + public static void checkNotNull(Object object, String elem) { + Preconditions.checkNotNull(object, "The '%s' can't be null", elem); + } + + public static void checkNotNull(Object object, String elem, String owner) { + Preconditions.checkNotNull(object, + "The '%s' of '%s' can't be null", + elem, owner); + } + + public static void checkNotEmpty(Collection collection, String elem) { + Preconditions.checkArgument(!collection.isEmpty(), + "The '%s' can't be empty", elem); + } + + public static void checkNotEmpty(Collection collection, String elem, String owner) { + Preconditions.checkArgument(!collection.isEmpty(), + "The '%s' of '%s' can't be empty", + elem, owner); + } + + public static void checkArgument(boolean expression, + @Nullable String message, + @Nullable Object... args) { + Preconditions.checkArgument(expression, message, args); + } + + public static void checkArgumentNotNull(Object object, + @Nullable String message, + @Nullable Object... args) { + Preconditions.checkArgument(object != null, message, args); + } + + public static void checkState(boolean expression, + @Nullable String message, + @Nullable Object... args) { + Preconditions.checkState(expression, message, args); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/ExceptionUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/ExceptionUtil.java new file mode 100644 index 0000000000..7142aea76a --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/ExceptionUtil.java @@ -0,0 +1,49 @@ +/* + * 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.util; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public final class ExceptionUtil { + + public static Throwable rootCause(Throwable e) { + Throwable cause = e; + while (cause.getCause() != null) { + cause = cause.getCause(); + } + return cause; + } + + public static RuntimeException transToRuntimeException(Throwable e) { + if (e instanceof RuntimeException) { + return (RuntimeException) e; + } + return new RuntimeException(rootCause(e).getMessage(), e); + } + + public static T futureGet(Future future) { + try { + return future.get(); + } catch (InterruptedException e) { + throw ExceptionUtil.transToRuntimeException(e); + } catch (ExecutionException e) { + throw ExceptionUtil.transToRuntimeException(e.getCause()); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/ExecutorUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/ExecutorUtil.java new file mode 100644 index 0000000000..f0ff7f1172 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/ExecutorUtil.java @@ -0,0 +1,111 @@ +/* + * 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.util; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.LinkedBlockingQueue; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.apache.hugegraph.concurrent.PausableScheduledThreadPool; + + + +public final class ExecutorUtil { + + public static ThreadPoolExecutor newDynamicThreadExecutor(String name, + int corePoolSize, + int maximumPoolSize) { + + long keepAliveTime = 60L; + TimeUnit unit = TimeUnit.SECONDS; + ThreadFactory factory = new BasicThreadFactory.Builder() + .namingPattern(name) + .build(); + CustomBlockingQueue workQueue = new CustomBlockingQueue<>(); + ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( + corePoolSize, + maximumPoolSize, + keepAliveTime, + unit, + workQueue, + factory, + new ThreadPoolExecutor.CallerRunsPolicy() + ); + + workQueue.setThreadPoolExecutor(threadPoolExecutor); + + return threadPoolExecutor; + } + + static class CustomBlockingQueue extends LinkedBlockingQueue { + private ThreadPoolExecutor threadPoolExecutor; + + public void setThreadPoolExecutor(ThreadPoolExecutor threadPoolExecutor) { + this.threadPoolExecutor = threadPoolExecutor; + } + + @Override + public boolean offer(E e) { + if (threadPoolExecutor.getPoolSize() < threadPoolExecutor.getMaximumPoolSize()) { + return false; + } + return super.offer(e); + } + } + + public static ExecutorService newFixedThreadPool(String name) { + return newFixedThreadPool(1, name); + } + + public static ExecutorService newFixedThreadPool(int size, String name) { + ThreadFactory factory = new BasicThreadFactory.Builder() + .namingPattern(name) + .build(); + return Executors.newFixedThreadPool(size, factory); + } + + public static ScheduledExecutorService newScheduledThreadPool(String name) { + return newScheduledThreadPool(1, name); + } + + public static ScheduledExecutorService newScheduledThreadPool(int size, + String name) { + ThreadFactory factory = new BasicThreadFactory.Builder() + .namingPattern(name) + .build(); + return Executors.newScheduledThreadPool(size, factory); + } + + public static PausableScheduledThreadPool newPausableScheduledThreadPool( + String name) { + return newPausableScheduledThreadPool(1, name); + } + + public static PausableScheduledThreadPool newPausableScheduledThreadPool( + int size, String name) { + ThreadFactory factory = new BasicThreadFactory.Builder() + .namingPattern(name) + .build(); + return new PausableScheduledThreadPool(size, factory); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/HashUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/HashUtil.java new file mode 100644 index 0000000000..fa382f7d10 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/HashUtil.java @@ -0,0 +1,44 @@ +/* + * 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.util; + +import java.nio.charset.Charset; + +import com.google.common.base.Charsets; +import com.google.common.hash.Hashing; + +public final class HashUtil { + + private static final Charset CHARSET = Charsets.UTF_8; + + public static byte[] hash(byte[] bytes) { + return Hashing.murmur3_32().hashBytes(bytes).asBytes(); + } + + public static String hash(String value) { + return Hashing.murmur3_32().hashString(value, CHARSET).toString(); + } + + public static byte[] hash128(byte[] bytes) { + return Hashing.murmur3_128().hashBytes(bytes).asBytes(); + } + + public static String hash128(String value) { + return Hashing.murmur3_128().hashString(value, CHARSET).toString(); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/InsertionOrderUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/InsertionOrderUtil.java new file mode 100644 index 0000000000..bb80ff602d --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/InsertionOrderUtil.java @@ -0,0 +1,64 @@ +/* + * 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.util; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public final class InsertionOrderUtil { + + public static Map newMap() { + return new LinkedHashMap<>(); + } + + public static Map newMap(int initialCapacity) { + return new LinkedHashMap<>(initialCapacity); + } + + public static Map newMap(Map origin) { + return new LinkedHashMap<>(origin); + } + + public static Set newSet() { + return new LinkedHashSet<>(); + } + + public static Set newSet(int initialCapacity) { + return new LinkedHashSet<>(initialCapacity); + } + + public static Set newSet(Set origin) { + return new LinkedHashSet<>(origin); + } + + public static List newList() { + return new ArrayList<>(); + } + + public static List newList(int initialCapacity) { + return new ArrayList<>(initialCapacity); + } + + public static List newList(List origin) { + return new ArrayList<>(origin); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/JsonUtilCommon.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/JsonUtilCommon.java new file mode 100644 index 0000000000..ad0acebeec --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/JsonUtilCommon.java @@ -0,0 +1,94 @@ +/* + * 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.util; + +import java.io.IOException; + +import org.apache.hugegraph.rest.SerializeException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Utility class for JSON operations. + */ +public final class JsonUtilCommon { + + /** + * ObjectMapper instance used for JSON operations. + */ + private static final ObjectMapper MAPPER = new ObjectMapper(); + + /** + * Registers a module with the ObjectMapper. + * + * @param module the module to register + */ + public static void registerModule(Module module) { + MAPPER.registerModule(module); + } + + /** + * Converts an object to a JSON string. + * + * @param object the object to convert + * @return the JSON string representation of the object + * @throws SerializeException if the object cannot be serialized + */ + public static String toJson(Object object) { + try { + return MAPPER.writeValueAsString(object); + } catch (JsonProcessingException e) { + throw new SerializeException("Failed to serialize object '%s'", e, object); + } + } + + /** + * Converts a JSON string to an object of the specified class. + * + * @param json the JSON string + * @param clazz the class of the object + * @return the object represented by the JSON string + * @throws SerializeException if the JSON string cannot be deserialized + */ + public static T fromJson(String json, Class clazz) { + try { + return MAPPER.readValue(json, clazz); + } catch (IOException e) { + throw new SerializeException("Failed to deserialize json '%s'", e, json); + } + } + + /** + * Converts a JsonNode to an object of the specified class. + * + * @param node the JsonNode + * @param clazz the class of the object + * @return the object represented by the JsonNode + * @throws SerializeException if the JsonNode cannot be deserialized + */ + public static T convertValue(JsonNode node, Class clazz) { + try { + return MAPPER.convertValue(node, clazz); + } catch (IllegalArgumentException e) { + throw new SerializeException("Failed to deserialize json node '%s'", e, node); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/Log.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/Log.java new file mode 100644 index 0000000000..0338272d83 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/Log.java @@ -0,0 +1,32 @@ +/* + * 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.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class Log { + + public static Logger logger(String name) { + return LoggerFactory.getLogger(name); + } + + public static Logger logger(Class clazz) { + return LoggerFactory.getLogger(clazz); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/LongEncoding.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/LongEncoding.java new file mode 100644 index 0000000000..761d72b907 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/LongEncoding.java @@ -0,0 +1,151 @@ +/* + * 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.util; + +public final class LongEncoding { + + private static final String B64_SYMBOLS = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; + + private static final String LENGTH_SYMBOLS = "0123456789ABCDEF"; + private static final char SORTABLE_NEG = LENGTH_SYMBOLS.charAt(0); + private static final char SIGNED_NEG = '-'; + + private static final long FULL_LONG = Long.MIN_VALUE; + + public static String encodeNumber(Object number) { + Number num = NumericUtil.convertToNumber(number); + long value = NumericUtil.numberToSortableLong(num); + return encodeSortable(value); + } + + public static Number decodeNumber(String str, Class clazz) { + long value = decodeSortable(str); + return NumericUtil.sortableLongToNumber(value, clazz); + } + + public static String encodeSortable(long num) { + boolean negative = false; + if (num < 0L) { + negative = true; + num += FULL_LONG; + } + + String encoded = encode(num, B64_SYMBOLS); + int length = encoded.length(); + E.checkArgument(length <= LENGTH_SYMBOLS.length(), + "Length symbols can't represent encoded number '%s'", + encoded); + StringBuilder sb = new StringBuilder(length + 2); + if (negative) { + sb.append(SORTABLE_NEG); + } + char len = LENGTH_SYMBOLS.charAt(length); + sb.append(len); + sb.append(encoded); + + return sb.toString(); + } + + public static long decodeSortable(String str) { + E.checkArgument(str.length() >= 2, + "Length of sortable encoded string must be >=2"); + boolean negative = str.charAt(0) == SORTABLE_NEG; + int lengthPos = 0; + if (negative) { + lengthPos = 1; + } + int length = B64_SYMBOLS.indexOf(str.charAt(lengthPos)); + E.checkArgument(length == str.length() - lengthPos - 1, + "Can't decode illegal string '%s' with wrong length", + str); + String encoded = str.substring(lengthPos + 1); + long value = decode(encoded, B64_SYMBOLS); + if (negative) { + value -= FULL_LONG; + } + return value; + } + + public static String encodeSignedB64(long value) { + boolean negative = false; + if (value < 0L) { + negative = true; + if (value == FULL_LONG) { + return "-80000000000"; + } + value = -value; + } + assert value >= 0L : value; + String encoded = encodeB64(value); + return negative ? SIGNED_NEG + encoded : encoded; + } + + public static long decodeSignedB64(String value) { + boolean negative = false; + if (!value.isEmpty() && value.charAt(0) == SIGNED_NEG) { + negative = true; + value = value.substring(1); + } + long decoded = decodeB64(value); + return negative ? -decoded : decoded; + } + + public static boolean validB64Char(char c) { + return B64_SYMBOLS.indexOf(c) != -1; + } + + public static String encodeB64(long num) { + return encode(num, B64_SYMBOLS); + } + + public static long decodeB64(String str) { + return decode(str, B64_SYMBOLS); + } + + public static long decode(String encoded, String symbols) { + final int B = symbols.length(); + E.checkArgument(B > 0, "The symbols parameter can't be empty"); + long num = 0L; + for (char ch : encoded.toCharArray()) { + num *= B; + int pos = symbols.indexOf(ch); + if (pos < 0) { + throw new NumberFormatException(String.format( + "Can't decode symbol '%s' in string '%s'", + ch, encoded)); + } + num += pos; + } + return num; + } + + public static String encode(long num, String symbols) { + final int B = symbols.length(); + E.checkArgument(num >= 0L, "Expected non-negative number: %s", num); + E.checkArgument(B > 0, "The symbols parameter can't be empty"); + + StringBuilder sb = new StringBuilder(); + do { + sb.append(symbols.charAt((int) (num % B))); + num /= B; + } while (num != 0L); + + return sb.reverse().toString(); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/NumericUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/NumericUtil.java new file mode 100644 index 0000000000..516170811a --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/NumericUtil.java @@ -0,0 +1,372 @@ +/* + * 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.util; + +import java.math.BigDecimal; +import java.nio.ByteBuffer; +import java.util.Date; +import java.util.function.Function; + +/** + * This file is copied verbatim from Apache Lucene NumericUtils.java + * Only the double/float to sortable long/int conversions are retained. + */ +public final class NumericUtil { + + private static final long FULL_LONG = Long.MIN_VALUE; + private static final int FULL_INT = Integer.MIN_VALUE; + private static final byte FULL_BYTE = Byte.MIN_VALUE; + + private NumericUtil() { + } + + /** + * Converts a double value to a sortable signed + * long. The value is converted by getting their IEEE 754 + * floating-point "double format" bit layout and then some bits + * are swapped, to be able to compare the result as long. By this the + * precision is not reduced, but the value can be easily used as a long. The + * sort order (including {@link Double#NaN}) is defined by + * {@link Double#compareTo}; {@code NaN} is greater than positive infinity. + * @param value input double value + * @return output sortable long value + * @see #sortableLongToDouble + */ + public static long doubleToSortableLong(double value) { + return sortableDoubleBits(Double.doubleToLongBits(value)); + } + + /** + * Converts a sortable long back to a double. + * @param value input double value + * @return output sortable long value + * @see #doubleToSortableLong + */ + public static double sortableLongToDouble(long value) { + return Double.longBitsToDouble(sortableDoubleBits(value)); + } + + /** + * Converts a float value to a sortable signed + * int. The value is converted by getting their IEEE 754 + * floating-point "float format" bit layout and then some bits are + * swapped, to be able to compare the result as int. By this the precision + * is not reduced, but the value can be easily used as an int. The sort order + * (including {@link Float#NaN}) is defined by {@link Float#compareTo}; + * {@code NaN} is greater than positive infinity. + * @param value input float value + * @return output sortable int value + * @see #sortableIntToFloat + */ + public static int floatToSortableInt(float value) { + return sortableFloatBits(Float.floatToIntBits(value)); + } + + /** + * Converts a sortable int back to a float. + * @param value input int value + * @return output sortable float value + * @see #floatToSortableInt + */ + public static float sortableIntToFloat(int value) { + return Float.intBitsToFloat(sortableFloatBits(value)); + } + + /** + * Converts IEEE 754 representation of a double to sortable order (or back + * to the original) + * @param bits The long format of a double value + * @return The sortable long value + */ + public static long sortableDoubleBits(long bits) { + return bits ^ ((bits >> 63) & 0x7fffffffffffffffL); + } + + /** + * Converts IEEE 754 representation of a float to sortable order (or back to + * the original) + * @param bits The int format of a float value + * @return The sortable int value + */ + public static int sortableFloatBits(int bits) { + /* + * Convert to its inverse digits if negative else keep the origin + * NOTE: (bits >> 31) is 0x00000000 if bits >= 0 + * (bits >> 31) is 0xFFFFFFFF if bits < 0 + */ + return bits ^ ((bits >> 31) & 0x7fffffff); + } + + public static long numberToSortableLong(Number number) { + if (number instanceof Double) { + return doubleToSortableLong(number.doubleValue()); + } else if (number instanceof Float) { + return floatToSortableInt(number.floatValue()); + } else if (number instanceof Long || number instanceof Integer || + number instanceof Short || number instanceof Byte) { + return number.longValue(); + } else if (number instanceof BigDecimal) { + BigDecimal bd = (BigDecimal) number; + boolean intNumber = bd.stripTrailingZeros().scale() <= 0; + return intNumber ? bd.longValueExact() : + doubleToSortableLong(bd.doubleValue()); + } + + // TODO: support other number types + throw unsupportedNumberType(number); + } + + public static Number sortableLongToNumber(long value, Class clazz) { + assert NumericUtil.isNumber(clazz); + + if (clazz == Double.class) { + return sortableLongToDouble(value); + } else if (clazz == Float.class) { + return sortableIntToFloat((int) value); + } else if (clazz == Long.class) { + return value; + } else if (clazz == Integer.class) { + return (int) value; + } else if (clazz == Short.class) { + return (short) value; + } else if (clazz == Byte.class) { + return (byte) value; + } + + // TODO: support other number types + throw unsupportedNumberType(clazz); + } + + public static byte[] numberToSortableBytes(Number number) { + if (number instanceof Long) { + return longToSortableBytes(number.longValue()); + } else if (number instanceof Double) { + long value = doubleToSortableLong(number.doubleValue()); + return longToSortableBytes(value); + } else if (number instanceof Float) { + int value = floatToSortableInt(number.floatValue()); + return intToSortableBytes(value); + } else if (number instanceof Integer || number instanceof Short) { + return intToSortableBytes(number.intValue()); + } else if (number instanceof Byte) { + return byteToSortableBytes(number.byteValue()); + } + + // TODO: support other number types + throw unsupportedNumberType(number); + } + + public static Number sortableBytesToNumber(byte[] bytes, Class clazz) { + assert NumericUtil.isNumber(clazz); + + if (clazz == Long.class) { + return sortableBytesToLong(bytes); + } else if (clazz == Double.class) { + return sortableLongToDouble(sortableBytesToLong(bytes)); + } else if (clazz == Float.class) { + return sortableIntToFloat(sortableBytesToInt(bytes)); + } else if (clazz == Integer.class) { + return sortableBytesToInt(bytes); + } else if (clazz == Short.class) { + return (short) sortableBytesToInt(bytes); + } else if (clazz == Byte.class) { + return sortableBytesToByte(bytes); + } + + // TODO: support other number types + throw unsupportedNumberType(clazz); + } + + public static Number minValueOf(Class clazz) { + E.checkArgumentNotNull(clazz, "The clazz can't be null"); + + if (Long.class.isAssignableFrom(clazz) || + Double.class.isAssignableFrom(clazz)) { + return Long.MIN_VALUE; + } + if (Integer.class.isAssignableFrom(clazz) || + Short.class.isAssignableFrom(clazz) || + Float.class.isAssignableFrom(clazz)) { + return Integer.MIN_VALUE; + } + if (Byte.class.isAssignableFrom(clazz)) { + return Byte.MIN_VALUE; + } + + // TODO: support other number types + throw unsupportedNumberType(clazz); + } + + public static Number maxValueOf(Class clazz) { + E.checkArgumentNotNull(clazz, "The clazz can't be null"); + + if (Long.class.isAssignableFrom(clazz) || + Double.class.isAssignableFrom(clazz)) { + return Long.MAX_VALUE; + } + if (Integer.class.isAssignableFrom(clazz) || + Float.class.isAssignableFrom(clazz) || + Short.class.isAssignableFrom(clazz)) { + return Integer.MAX_VALUE; + } + if (Byte.class.isAssignableFrom(clazz)) { + return Byte.MAX_VALUE; + } + + // TODO: support other number types + throw unsupportedNumberType(clazz); + } + + public static byte[] longToSortableBytes(long value) { + return longToBytes(value + FULL_LONG); + } + + public static long sortableBytesToLong(byte[] bytes) { + return bytesToLong(bytes) - FULL_LONG; + } + + public static byte[] intToSortableBytes(int value) { + return intToBytes(value + FULL_INT); + } + + public static int sortableBytesToInt(byte[] bytes) { + return bytesToInt(bytes) - FULL_INT; + } + + public static byte[] byteToSortableBytes(byte value) { + value += FULL_BYTE; + return new byte[]{value}; + } + + public static byte sortableBytesToByte(byte[] bytes) { + assert bytes.length == 1; + byte value = bytes[0]; + value -= FULL_BYTE; + return value; + } + + public static byte[] longToBytes(long value) { + ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); + buffer.putLong(value); + return buffer.array(); + } + + public static long bytesToLong(byte[] bytes) { + assert bytes.length == Long.BYTES; + return ByteBuffer.wrap(bytes).getLong(); + } + + public static byte[] intToBytes(int value) { + ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); + buffer.putInt(value); + return buffer.array(); + } + + public static int bytesToInt(byte[] bytes) { + assert bytes.length == Integer.BYTES; + return ByteBuffer.wrap(bytes).getInt(); + } + + public static boolean isNumber(Object value) { + if (value == null) { + return false; + } + return isNumber(value.getClass()); + } + + public static boolean isNumber(Class clazz) { + if (clazz.isPrimitive()) { + return clazz == int.class || clazz == long.class || + clazz == float.class || clazz == double.class || + clazz == short.class || clazz == byte.class; + } + return Number.class.isAssignableFrom(clazz); + } + + public static Number convertToNumber(Object value) { + if (value == null) { + return null; + } + + Number number; + if (isNumber(value)) { + number = (Number) value; + } else { + if (value instanceof Date) { + number = ((Date) value).getTime(); + } else { + // TODO: add some more types to convert + number = new BigDecimal(value.toString()); + } + } + return number; + } + + /** + * Compare object with a number, the object should be a number, + * or it can be converted to a BigDecimal + * @param first might be number or string + * @param second must be number + * @return 0 if first is numerically equal to second; + * a negative int if first is numerically less than second; + * a positive int if first is numerically greater than second. + */ + public static int compareNumber(Object first, Number second) { + if (first == null) { + E.checkArgument(first != null, + "The first parameter can't be null"); + } + if (second == null) { + E.checkArgument(second != null, + "The second parameter can't be null"); + } + + if (first instanceof Number && first instanceof Comparable && + first.getClass().equals(second.getClass())) { + @SuppressWarnings("unchecked") + Comparable cmpFirst = (Comparable) first; + return cmpFirst.compareTo(second); + } + + Function toBig = (number) -> { + try { + return new BigDecimal(number.toString()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(String.format( + "Can't compare between '%s' and '%s', " + + "they must be numbers", first, second)); + } + }; + + BigDecimal n1 = toBig.apply(first); + BigDecimal n2 = toBig.apply(second); + + return n1.compareTo(n2); + } + + private static IllegalArgumentException unsupportedNumberType(Class c) { + return new IllegalArgumentException(String.format( + "Unsupported number type: %s", c.getSimpleName())); + } + + private static IllegalArgumentException unsupportedNumberType(Number num) { + return new IllegalArgumentException(String.format( + "Unsupported number type: %s(%s)", + num.getClass().getSimpleName(), num)); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/OrderLimitMap.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/OrderLimitMap.java new file mode 100644 index 0000000000..b711e3e585 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/OrderLimitMap.java @@ -0,0 +1,103 @@ +/* + * 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.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +import com.google.common.base.Functions; +import com.google.common.collect.Ordering; + +public class OrderLimitMap, V extends Comparable> extends TreeMap { + + private static final long serialVersionUID = 756490437953358633L; + + private final int capacity; + private final Map valueMap; + + private static > Ordering incr() { + return Ordering.from(Comparable::compareTo); + } + + private static > Ordering decr() { + return Ordering.from((V o1, V o2) -> -o1.compareTo(o2)); + } + + public OrderLimitMap(int capacity) { + this(capacity, false); + } + + public OrderLimitMap(int capacity, boolean incr) { + this(capacity, incr ? incr() : decr(), new HashMap<>()); + } + + private OrderLimitMap(int capacity, Ordering ordering, + HashMap valueMap) { + /* + * onResultOf: for getting the value for the key from value map + * compound: keep insertion order + */ + super(ordering.onResultOf(Functions.forMap(valueMap)) + .compound(Ordering.natural())); + E.checkArgument(capacity > 0, "The capacity must be > 0"); + this.capacity = capacity; + this.valueMap = valueMap; + } + + @Override + public V put(K k, V v) { + if (this.valueMap.containsKey(k)) { + super.remove(k); + } else if (this.valueMap.size() >= this.capacity) { + K key = super.lastKey(); + super.remove(key); + this.valueMap.remove(key); + } + this.valueMap.put(k, v); + return super.put(k, v); + } + + @Override + public V get(Object key) { + return this.valueMap.get(key); + } + + @Override + public V getOrDefault(Object key, V defaultValue) { + return this.valueMap.getOrDefault(key, defaultValue); + } + + @Override + public boolean containsKey(Object key) { + return this.valueMap.containsKey(key); + } + + public Map topN(int n) { + E.checkArgument(n > 0, "'N' Must be positive, but got '%s'", n); + Map top = InsertionOrderUtil.newMap(); + int i = 0; + for (Map.Entry entry : this.entrySet()) { + top.put(entry.getKey(), entry.getValue()); + if (++i >= n) { + break; + } + } + return top; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/ReflectionUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/ReflectionUtil.java new file mode 100644 index 0000000000..f48d5b6c78 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/ReflectionUtil.java @@ -0,0 +1,124 @@ +/* + * 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.util; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.apache.hugegraph.iterator.ExtendableIterator; +import com.google.common.collect.Lists; +import com.google.common.reflect.ClassPath; +import com.google.common.reflect.ClassPath.ClassInfo; + +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; +import javassist.NotFoundException; + +public final class ReflectionUtil { + + public static boolean isSimpleType(Class type) { + return type.isPrimitive() || + type.equals(String.class) || + type.equals(Boolean.class) || + type.equals(Character.class) || + NumericUtil.isNumber(type); + } + + public static List getMethodsAnnotatedWith( + Class type, + Class annotation, + boolean withSuperClass) { + final List methods = new LinkedList<>(); + Class klass = type; + do { + for (Method method : klass.getDeclaredMethods()) { + if (method.isAnnotationPresent(annotation)) { + methods.add(method); + } + } + klass = klass.getSuperclass(); + } while (klass != Object.class && withSuperClass); + return methods; + } + + public static List getMethodsAnnotatedWith( + CtClass type, + Class annotation, + boolean withSuperClass) + throws NotFoundException { + final List methods = new LinkedList<>(); + + CtClass klass = type; + do { + for (CtMethod method : klass.getDeclaredMethods()) { + if (method.hasAnnotation(annotation)) { + methods.add(method); + } + } + klass = klass.getSuperclass(); + } while (klass != null && withSuperClass); + return methods; + } + + public static Iterator classes(String... packages) + throws IOException { + ClassPath path = ClassPath.from(ReflectionUtil.class.getClassLoader()); + ExtendableIterator results = new ExtendableIterator<>(); + for (String p : packages) { + results.extend(path.getTopLevelClassesRecursive(p).iterator()); + } + return results; + } + + public static List superClasses(String clazz) + throws NotFoundException { + CtClass klass = ClassPool.getDefault().get(clazz); + CtClass parent = klass.getSuperclass(); + + List results = new LinkedList<>(); + while (parent != null) { + results.add(parent.getName()); + parent = parent.getSuperclass(); + } + return Lists.reverse(results); + } + + public static List nestedClasses(String clazz) + throws NotFoundException { + CtClass klass = ClassPool.getDefault().get(clazz); + + List results = new LinkedList<>(); + for (CtClass nested : klass.getNestedClasses()) { + results.add(nested.getName()); + } + return results; + } + + public static String packageName(String clazz) { + int offset = clazz.lastIndexOf("."); + if (offset > 0) { + return clazz.substring(0, offset); + } + return ""; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/StringUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/StringUtil.java new file mode 100644 index 0000000000..f144957db5 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/StringUtil.java @@ -0,0 +1,123 @@ +/* + * 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.util; + +public final class StringUtil { + + public static Chars[] splitToCharsArray(String text, String delimiter) { + E.checkArgument(delimiter.length() > 0, + "The delimiter can't be empty"); + Chars[] buffer = new Chars[text.length()]; + int count = Chars.split(text, delimiter, buffer); + if (count == buffer.length) { + return buffer; + } + Chars[] result = new Chars[count]; + System.arraycopy(buffer, 0, result, 0, count); + return result; + } + + public static String[] split(String text, String delimiter) { + E.checkArgument(delimiter.length() > 0, + "The delimiter can't be empty"); + Chars[] buffer = new Chars[text.length()]; + int count = Chars.split(text, delimiter, buffer); + String[] result = new String[count]; + for (int i = 0; i < count; i++) { + result[i] = buffer[i].toString(); + } + return result; + } + + public static class Chars implements CharSequence { + + private final char[] chars; + private final int start; + private final int end; + + public Chars(char[] chars, int start, int end) { + E.checkArgument(0 < start && start < chars.length || start == 0, + "Invalid start parameter %s", start); + E.checkArgument(start <= end && end <= chars.length, + "Invalid end parameter %s", end); + this.chars = chars; + this.start = start; + this.end = end; + } + + @Override + public int length() { + return this.end - this.start; + } + + @Override + public char charAt(int index) { + return this.chars[this.start + index]; + } + + @Override + public CharSequence subSequence(int start, int end) { + return new Chars(this.chars, this.start + start, this.start + end); + } + + @Override + public boolean equals(Object object) { + if (!(object instanceof Chars)) { + return false; + } + Chars other = (Chars) object; + return this.toString().equals(other.toString()); + } + + @Override + public int hashCode() { + return this.toString().hashCode(); + } + + @Override + public String toString() { + return new String(this.chars, this.start, this.length()); + } + + public static Chars of(String string) { + return new Chars(string.toCharArray(), 0, string.length()); + } + + public static Chars[] of(String... strings) { + Chars[] results = new Chars[strings.length]; + for (int i = 0; i < strings.length; i++) { + results[i] = Chars.of(strings[i]); + } + return results; + } + + public static int split(String text, String delimiter, Chars[] buffer) { + int count = 0; + int from = 0; + char[] chars = text.toCharArray(); + for (int to; (to = text.indexOf(delimiter, from)) >= 0; + from = to + delimiter.length()) { + buffer[count++] = new Chars(chars, from, to); + } + if (from < text.length()) { + buffer[count++] = new Chars(chars, from, text.length()); + } + return count; + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/TimeUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/TimeUtil.java new file mode 100644 index 0000000000..8a6b9abeb2 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/TimeUtil.java @@ -0,0 +1,59 @@ +/* + * 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.util; + +import java.time.Duration; +import java.util.Date; + +public final class TimeUtil { + + @SuppressWarnings("deprecation") + public static long BASE_TIME = new Date(2017 - 1900, 10, 28).getTime(); + + public static long timeGen() { + return System.currentTimeMillis() - BASE_TIME; + } + + public static long timeGen(Date date) { + return date.getTime() - BASE_TIME; + } + + public static long timeGen(long time) { + return time - BASE_TIME; + } + + public static long tillNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + public static String readableTime(long time) { + if (time > 60 * 1000) { + // Remove the milliseconds part + time = time / 1000 * 1000; + } + Duration duration = Duration.ofMillis(time); + return duration.toString() + .substring(2) + .replaceAll("(\\d[HMS])(?!$)", "$1 ") + .toLowerCase(); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/UnitUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/UnitUtil.java new file mode 100644 index 0000000000..09e1ff6379 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/UnitUtil.java @@ -0,0 +1,181 @@ +/* + * 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.util; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.Duration; + +public final class UnitUtil { + + public static double bytesToMB(long bytes) { + return doubleWith2Scale(bytes / (double) Bytes.MB); + } + + public static double bytesToGB(long bytes) { + return doubleWith2Scale(bytes / (double) Bytes.GB); + } + + public static double doubleWith2Scale(double value) { + BigDecimal decimal = new BigDecimal(value); + return decimal.setScale(2, RoundingMode.HALF_UP).doubleValue(); + } + + public static String bytesToReadableString(long bytes) { + // NOTE: FileUtils.byteCountToDisplaySize() lost decimal precision + final String[] units = {"B", "KB", "MB", "GB", "TB", "PB", "EB"}; + if (bytes <= 0L) { + return "0 B"; + } + int i = (int) (Math.log(bytes) / Math.log(1024)); + E.checkArgument(i < units.length, + "The bytes parameter is out of %s unit: %s", + units[units.length - 1], bytes); + double value = bytes / Math.pow(1024, i); + if (value % 1L == 0L) { + return ((long) value) + " " + units[i]; + } else { + return doubleWith2Scale(value) + " " + units[i]; + } + } + + public static long bytesFromReadableString(String valueWithUnit) { + int spacePos = valueWithUnit.indexOf(" "); + E.checkArgument(spacePos >= 0, + "Invalid readable bytes '%s', " + + "expect format like '10 MB'", valueWithUnit); + String unit = valueWithUnit.substring(spacePos + 1); + + long factor; + switch (unit.trim().toUpperCase()) { + case "B": + case "BYTE": + case "BYTES": + factor = 1L; + break; + case "KB": + case "KIB": + factor = Bytes.KB; + break; + case "MB": + case "MIB": + factor = Bytes.MB; + break; + case "GB": + case "GIB": + factor = Bytes.GB; + break; + case "TB": + case "TIB": + factor = Bytes.TB; + break; + case "PB": + case "PIB": + factor = Bytes.PB; + break; + case "EB": + case "EIB": + factor = Bytes.EB; + break; + default: + throw new IllegalArgumentException("Unrecognized unit " + unit); + } + + double value; + try { + value = Double.parseDouble(valueWithUnit.substring(0, spacePos)); + } catch (Exception e) { + throw new IllegalArgumentException(String.format( + "Invalid parameter(not number): '%s'", valueWithUnit), e); + } + value = value * factor; + E.checkArgument(value <= Long.MAX_VALUE, + "The value %s from parameter '%s' is out of range", + value, valueWithUnit); + return (long) value; + } + + public static String timestampToReadableString(long time) { + Duration duration = Duration.ofMillis(time); + long days = duration.toDays(); + long hours = duration.toHours(); + long minutes = duration.toMinutes(); + long seconds = duration.getSeconds(); + + if (days > 0) { + return String.format("%dd%dh%dm%ds", + days, + hours % 24, + minutes % 60, + seconds % 60); + } else if (hours > 0) { + return String.format("%dh%dm%ds", + hours, + minutes % 60, + seconds % 60); + } else if (minutes > 0) { + return String.format("%dm%ds", + minutes, + seconds % 60); + } else if (seconds > 0) { + long ms = duration.toMillis() % 1000L; + if (ms > 0L) { + return String.format("%ds%dms", seconds, ms); + } else { + return String.format("%ds", seconds); + } + } else { + return String.format("%dms", duration.toMillis()); + } + } + + public static long timestampFromReadableString(String valueWithUnit) { + long ms = 0L; + // Adapt format 'nDnHnMnS' to 'PnYnMnDTnHnMnS' + String formatDuration = valueWithUnit.toUpperCase(); + if (formatDuration.indexOf('D') >= 0) { + // Contains days + assert !formatDuration.contains("MS"); + formatDuration = "P" + formatDuration.replace("D", "DT"); + } else { + // Not exists days + int msPos = formatDuration.indexOf("MS"); + // If contains ms, remove the ms part + if (msPos >= 0) { + int sPos = formatDuration.indexOf("S"); + if (0 <= sPos && sPos < msPos) { + // If contains second part + sPos += 1; + ms = Long.parseLong(formatDuration.substring(sPos, msPos)); + ms %= 1000L; + formatDuration = formatDuration.substring(0, sPos); + } else { + // Not contains second part, only exists ms + ms = Long.parseLong(formatDuration.substring(0, msPos)); + return ms; + } + } else { + assert formatDuration.endsWith("S"); + } + formatDuration = "PT" + formatDuration; + } + + Duration duration = Duration.parse(formatDuration); + return duration.toMillis() + ms; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/VersionUtil.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/VersionUtil.java new file mode 100644 index 0000000000..b49adda87a --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/util/VersionUtil.java @@ -0,0 +1,236 @@ +/* + * 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.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.Objects; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +public final class VersionUtil { + + /** + * Compare if a version is inside a range [begin, end) + * @param version The version to be compared + * @param begin The lower bound of the range + * @param end The upper bound of the range + * @return true if belong to the range, otherwise false + */ + public static boolean match(Version version, String begin, String end) { + E.checkArgumentNotNull(version, "The version to match is null"); + return version.compareTo(new Version(begin)) >= 0 && + version.compareTo(new Version(end)) < 0; + } + + /** + * Compare if a version is greater than the other one (inclusive) + * @param version The version to be compared + * @param other The lower bound of the range + * @return true if it's greater than the other, otherwise false + */ + public static boolean gte(String version, String other) { + E.checkArgumentNotNull(version, "The version to match is null"); + return new Version(version).compareTo(new Version(other)) >= 0; + } + + /** + * Check whether a component version is matched expected range, + * throw an exception if it's not matched. + * @param version The version to be checked + * @param begin The lower bound of the range + * @param end The upper bound of the range + * @param component The owner component of version + */ + public static void check(Version version, String begin, String end, + String component) { + E.checkState(VersionUtil.match(version, begin, end), + "The version %s of '%s' is not in [%s, %s)", + version, component, begin, end); + } + + /** + * Get implementation version from manifest in jar + * @param clazz The class to be load from jar package + * @return The implementation version + */ + public static String getImplementationVersion(Class clazz) { + /* + * We don't use Package.getImplementationVersion() due to + * a duplicate package would override the origin package info. + */ + String className = clazz.getSimpleName() + ".class"; + String classPath = Objects.requireNonNull(clazz.getResource(className)).toString(); + if (!classPath.startsWith("jar:file:")) { + // Class not from JAR + return null; + } + int offset = classPath.lastIndexOf("!"); + assert offset > 0; + // Get manifest file path + String manifestPath = classPath.substring(0, offset + 1); + return getImplementationVersion(manifestPath); + } + + public static String getImplementationVersion(String manifestPath) { + manifestPath += "/META-INF/MANIFEST.MF"; + + Manifest manifest; + try { + manifest = new Manifest(new URL(manifestPath).openStream()); + } catch (IOException ignored) { + return null; + } + return manifest.getMainAttributes() + .getValue(Attributes.Name.IMPLEMENTATION_VERSION); + } + + /** + * Get version from pom.xml + * @return The pom version + */ + public static String getPomVersion() { + String cmd = "mvn help:evaluate -Dexpression=project.version " + + "-q -DforceStdout"; + Process process = null; + InputStreamReader isr = null; + try { + process = Runtime.getRuntime().exec(cmd); + process.waitFor(); + + isr = new InputStreamReader(process.getInputStream()); + BufferedReader br = new BufferedReader(isr); + return br.readLine(); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + if (isr != null) { + try { + isr.close(); + } catch (Exception ignored) { + // pass + } + } + + // Destroy child process + if (process != null) { + process.destroy(); + } + } + } + + public static class Version implements Comparable { + + public static Version of(Class clazz) { + return Version.of(clazz, null); + } + + public static Version of(Class clazz, String defaultValue) { + String v = getImplementationVersion(clazz); + if (v == null) { + v = defaultValue; + } + return v == null ? null : new Version(v); + } + + public static Version of(String version) { + return new Version(version); + } + + /************************** Version define **************************/ + + private final String version; + private final int[] parts; + + public Version(String version) { + E.checkArgumentNotNull(version, "The version is null"); + E.checkArgument(version.matches("[0-9]+(\\.[0-9]+)*"), + "Invalid version format: %s", version); + this.version = version; + this.parts = parseVersion(version); + } + + private static int[] parseVersion(String version) { + String[] parts = version.split("\\."); + int[] partsNumber = new int[parts.length]; + for (int i = 0; i < parts.length; i++) { + partsNumber[i] = Integer.parseInt(parts[i]); + } + return partsNumber; + } + + public final String get() { + return this.version; + } + + @Override + public int compareTo(Version that) { + if (that == null) { + return 1; + } + int[] thisParts = this.parts; + int[] thatParts = that.parts; + int length = Math.max(thisParts.length, thatParts.length); + for (int i = 0; i < length; i++) { + int thisPart = i < thisParts.length ? thisParts[i] : 0; + int thatPart = i < thatParts.length ? thatParts[i] : 0; + if (thisPart < thatPart) { + return -1; + } + if (thisPart > thatPart) { + return 1; + } + } + return 0; + } + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (this.getClass() != that.getClass()) { + return false; + } + return this.compareTo((Version) that) == 0; + } + + @Override + public int hashCode() { + int hash = 0; + for (int i = this.parts.length - 1; i >= 0; i--) { + int part = this.parts[i]; + if (part == 0 && hash == 0) { + continue; + } + hash = 31 * hash + Integer.hashCode(part); + } + return hash; + } + + @Override + public String toString() { + return this.version; + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/version/CommonVersion.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/version/CommonVersion.java new file mode 100644 index 0000000000..73342fdaaa --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/version/CommonVersion.java @@ -0,0 +1,28 @@ +/* + * 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.version; + +import org.apache.hugegraph.util.VersionUtil.Version; + +public class CommonVersion { + + public static final String NAME = "hugegraph-common"; + + // The second parameter of Version.of() is for all-in-one JAR + public static final Version VERSION = Version.of(CommonVersion.class, "1.5.0"); +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/testutil/AssertTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/testutil/AssertTest.java new file mode 100644 index 0000000000..53f60247e9 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/testutil/AssertTest.java @@ -0,0 +1,444 @@ +/* + * 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.testutil; + +import org.apache.hugegraph.unit.BaseUnitTest; +import org.junit.Test; + +public class AssertTest extends BaseUnitTest { + + @Test + public void testAssertEquals() { + Assert.assertEquals((byte) 1, Byte.valueOf("1")); + Assert.assertEquals((short) 1, Short.valueOf("1")); + Assert.assertEquals('1', Character.valueOf('1')); + Assert.assertEquals(1, Integer.valueOf("1")); + Assert.assertEquals(1L, Long.valueOf("1")); + Assert.assertEquals(1f, Float.valueOf("1")); + Assert.assertEquals(1d, Double.valueOf("1")); + } + + @Test + public void testAssertEqualsWithError() { + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals((byte) 1, "1"); + }, e -> { + Assert.assertContains("expected: java.lang.Byte", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals((short) 1, "1"); + }, e -> { + Assert.assertContains("expected: java.lang.Short", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals('1', "1"); + }, e -> { + Assert.assertContains("expected: java.lang.Character", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1, "1"); + }, e -> { + Assert.assertContains("expected: java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1L, "1"); + }, e -> { + Assert.assertContains("expected: java.lang.Long", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1f, "1.0"); + }, e -> { + Assert.assertContains("expected: java.lang.Float", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1d, "1.0"); + }, e -> { + Assert.assertContains("expected: java.lang.Double", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1f, "1"); + }, e -> { + Assert.assertContains("expected:<1.0> but was:<1>", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1d, "1"); + }, e -> { + Assert.assertContains("expected:<1.0> but was:<1>", + e.getMessage()); + }); + } + + @Test + public void testAssertEqualsOfIntWithError() { + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1, (Byte) (byte) 1); + }, e -> { + Assert.assertContains("expected: java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1, (Short) (short) 1); + }, e -> { + Assert.assertContains("expected: java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1, (Character) '1'); + }, e -> { + Assert.assertContains("expected: java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1, (Long) 1L); + }, e -> { + Assert.assertContains("expected: java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1, (Float) 1f); + }, e -> { + Assert.assertContains("expected:<1> but was:<1.0>", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1, (Double) 1d); + }, e -> { + Assert.assertContains("expected:<1> but was:<1.0>", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1, "1.0"); + }, e -> { + Assert.assertContains("expected:<1> but was:<1.0>", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1, (Byte) (byte) 2); + }, e -> { + Assert.assertContains("expected:<1> but was:<2>", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertEquals(1, null); + }, e -> { + Assert.assertContains("expected:<1> but was:", + e.getMessage()); + }); + } + + @Test + public void testAssertThrows() { + Assert.assertThrows(NullPointerException.class, () -> { + throw new NullPointerException(); + }); + Assert.assertThrows(RuntimeException.class, () -> { + throw new RuntimeException(); + }); + + Throwable exception = Assert.assertThrows(RuntimeException.class, () -> { + throw new RuntimeException("fake-error"); + }); + Assert.assertInstanceOf(RuntimeException.class, exception); + Assert.assertEquals("fake-error", exception.getMessage()); + + Assert.assertThrows(RuntimeException.class, () -> { + throw new RuntimeException("fake-error"); + }, e -> { + Assert.assertEquals("fake-error", e.getMessage()); + }); + } + + @Test + public void testAssertThrowsWithTypeError() { + try { + Assert.assertThrows(NullPointerException.class, () -> { + // pass + }); + Assert.fail("Expect error"); + } catch (AssertionError e) { + Assert.assertContains("java.lang.NullPointerException", e.getMessage()); + } + + try { + Assert.assertThrows(NullPointerException.class, () -> { + throw new RuntimeException(); + }); + Assert.fail("Expect error"); + } catch (AssertionError e) { + Assert.assertContains("java.lang.NullPointerException", e.getMessage()); + Assert.assertContains("java.lang.RuntimeException", e.getMessage()); + } + } + + @Test + public void testAssertThrowsWithMessageError() { + try { + Assert.assertThrows(RuntimeException.class, () -> { + throw new RuntimeException("fake-error"); + }, e -> { + Assert.assertEquals("fake-error-typo", e.getMessage()); + }); + Assert.fail("Expect error"); + } catch (AssertionError e) { + Assert.assertContains("expected: but was:", + e.getMessage()); + } + } + + @Test + public void testAssertGt() { + Assert.assertGt((byte) 1, Byte.valueOf("2")); + Assert.assertGt((short) 1, Short.valueOf("2")); + Assert.assertGt(1, Integer.valueOf("2")); + Assert.assertGt(1L, Long.valueOf("2")); + Assert.assertGt(1f, Float.valueOf("1.01")); + Assert.assertGt(1d, Double.valueOf("1.01")); + + Assert.assertGt((byte) 1, (byte) 2); + Assert.assertGt((short) 1, (short) 2); + Assert.assertGt(1, 2); + Assert.assertGt(1L, 2L); + Assert.assertGt(1f, 1.01f); + Assert.assertGt(1d, 1.01d); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGt(1, 0); + }, e -> { + Assert.assertContains("Expected: a number > 1", e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGt(1, null); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGt(1, (byte) 2); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGt(1, 1.1); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGt(1, '2'); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGt(0.9, 1); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Double", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGt(0.9d, 0.98f); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Double", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGt(0.9f, 0.98d); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Float", + e.getMessage()); + }); + } + + @Test + public void testAssertGte() { + Assert.assertGte((byte) 1, Byte.valueOf("2")); + Assert.assertGte((short) 1, Short.valueOf("2")); + Assert.assertGte(1, Integer.valueOf("2")); + Assert.assertGte(1L, Long.valueOf("2")); + Assert.assertGte(1f, Float.valueOf("1.01")); + Assert.assertGte(1d, Double.valueOf("1.01")); + + Assert.assertGte((byte) 1, Byte.valueOf("1")); + Assert.assertGte((short) 1, Short.valueOf("1")); + Assert.assertGte(1, Integer.valueOf("1")); + Assert.assertGte(1L, Long.valueOf("1")); + Assert.assertGte(1f, Float.valueOf("1")); + Assert.assertGte(1d, Double.valueOf("1")); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGte(1, 0); + }, e -> { + Assert.assertContains("Expected: a number >= 1", e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGte(1, 1.1); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGte(1, '2'); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Integer", + e.getMessage()); + }); + } + + @Test + public void testAssertLt() { + Assert.assertLt((byte) 1, Byte.valueOf("0")); + Assert.assertLt((short) 1, Short.valueOf("0")); + Assert.assertLt(1, Integer.valueOf("0")); + Assert.assertLt(1L, Long.valueOf("0")); + Assert.assertLt(1f, Float.valueOf("0.99")); + Assert.assertLt(1d, Double.valueOf("0.99")); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertLt(1, 2); + }, e -> { + Assert.assertContains("Expected: a number < 1", e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGt(1, 0.9); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertGt(1, '0'); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Integer", + e.getMessage()); + }); + } + + @Test + public void testAssertLte() { + Assert.assertLte((byte) 1, Byte.valueOf("0")); + Assert.assertLte((short) 1, Short.valueOf("0")); + Assert.assertLte(1, Integer.valueOf("0")); + Assert.assertLte(1L, Long.valueOf("0")); + Assert.assertLte(1f, Float.valueOf("0.99")); + Assert.assertLte(1d, Double.valueOf("0.99")); + + Assert.assertLte((byte) 1, Byte.valueOf("1")); + Assert.assertLte((short) 1, Short.valueOf("1")); + Assert.assertLte(1, Integer.valueOf("1")); + Assert.assertLte(1L, Long.valueOf("1")); + Assert.assertLte(1f, Float.valueOf("1")); + Assert.assertLte(1d, Double.valueOf("1")); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertLte(1, 2); + }, e -> { + Assert.assertContains("Expected: a number <= 1", e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertLte(1, 0.9); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Integer", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertLte(1, '0'); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Integer", + e.getMessage()); + }); + } + + @Test + public void testAssertContains() { + Assert.assertContains("test", "test"); + Assert.assertContains("test", "hellotest"); + Assert.assertContains("test", "test123"); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertContains("test123", "test"); + }, e -> { + Assert.assertContains("Expected: a string containing", + e.getMessage()); + }); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertContains("null", null); + }, e -> { + Assert.assertContains("Expected: a string containing", + e.getMessage()); + }); + + Assert.assertThrows(NullPointerException.class, () -> { + Assert.assertContains(null, "null"); + }, e -> { + Assert.assertNull(e.getMessage()); + }); + } + + @Test + public void testAssertInstanceOf() { + Assert.assertInstanceOf(Integer.class, 1); + Assert.assertInstanceOf(Double.class, 1.0); + Assert.assertInstanceOf(String.class, "1.0"); + Assert.assertInstanceOf(BaseUnitTest.class, this); + + Assert.assertThrows(AssertionError.class, () -> { + Assert.assertInstanceOf(Float.class, 1); + }, e -> { + Assert.assertContains("Expected: an instance of java.lang.Float", + e.getMessage()); + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/testutil/WhiteboxTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/testutil/WhiteboxTest.java new file mode 100644 index 0000000000..15124edbcc --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/testutil/WhiteboxTest.java @@ -0,0 +1,258 @@ +/* + * 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.testutil; + +import org.junit.Test; + +public class WhiteboxTest { + + @Test + public void testGetStaticInternalState() { + Assert.assertEquals(1, Whitebox.getInternalState(Test1.class, + "staticValue")); + Test1 test1 = newTest(); + Assert.assertEquals(1, Whitebox.getInternalState(test1, "staticValue")); + Assert.assertEquals(2, Whitebox.getInternalState(test1, + "test2.staticValue")); + } + + @Test + public void testSetStaticInternalState() { + try { + Whitebox.setInternalState(Test1.class, "staticValue", 11); + Assert.assertEquals(11, Test1.staticValue); + + Test1 test1 = newTest(); + Whitebox.setInternalState(test1, "staticValue", 111); + Assert.assertEquals(111, Test1.staticValue); + + Whitebox.setInternalState(test1, "test2.staticValue", 22); + Assert.assertEquals(22, Test2.staticValue); + } finally { + Whitebox.setInternalState(Test1.class, "staticValue", 1); + Whitebox.setInternalState(Test2.class, "staticValue", 2); + } + } + + @Test + public void testGetInternalState() { + Test1 test1 = newTest(); + Assert.assertEquals(1, Whitebox.getInternalState(test1, "ivalue")); + Assert.assertEquals(2f, Whitebox.getInternalState(test1, + "test2.finalValue")); + Assert.assertEquals("3", Whitebox.getInternalState(test1, + "test2.test3.str")); + + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.getInternalState(test1, "ivalue2"); + }); + + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.getInternalState(test1, "test2.valueNotExist"); + }); + } + + @Test + public void testSetInternalState() { + Test1 test1 = newTest(); + + Whitebox.setInternalState(test1, "ivalue", 11); + Assert.assertEquals(11, Whitebox.getInternalState(test1, "ivalue")); + Assert.assertEquals(11, test1.ivalue); + + Whitebox.setInternalState(test1, "test2.finalValue", 22f); + Assert.assertEquals(22f, Whitebox.getInternalState(test1, + "test2.finalValue")); + + Whitebox.setInternalState(test1, "test2.test3.str", "33"); + Assert.assertEquals("33", Whitebox.getInternalState(test1, + "test2.test3.str")); + + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.setInternalState(test1, "ivalue2", 11); + }); + + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.setInternalState(test1, "test2.valueNotExist", 22f); + }); + + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.setInternalState(test1, "test2.finalValue", 22d); + }); + + Assert.assertThrows(RuntimeException.class, () -> { + test1.test2 = null; + Whitebox.setInternalState(test1, "test2.finalValue", 22f); + }, e -> { + Assert.assertContains("Can't set value on null field", + e.getMessage()); + }); + } + + @Test + public void testSetInternalFinalState() { + Test1 test1 = newTest(); + Assert.assertEquals(1, test1.finalValue); + + Whitebox.setInternalState(test1, "finalValue", 2); + Assert.assertEquals(2, Whitebox.getInternalState(test1, "finalValue")); + + Whitebox.setInternalState(test1, "finalValue", 3); + Assert.assertEquals(3, Whitebox.getInternalState(test1, "finalValue")); + + Whitebox.setInternalState(test1, "test2.finalValue", 22f); + Assert.assertEquals(22f, Whitebox.getInternalState(test1, + "test2.finalValue")); + + // FIXME: seems don't take effect!!! + Assert.assertEquals(1, test1.finalValue); + Assert.assertEquals(2f, test1.test2.finalValue, 0f); + } + + @Test + public void testInvokeStatic() { + Assert.assertEquals(1, Whitebox.invokeStatic(Test1.class, "svalue")); + Assert.assertEquals(2, Whitebox.invokeStatic(Test1.class, "svalue", 2)); + Assert.assertEquals(2, Whitebox.invokeStatic(Test1.class, "svalue", + new Integer(2))); + Assert.assertEquals(2d, Whitebox.invokeStatic(Test1.class, + new Class[]{Object.class}, + "svalue", 2d)); + + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.invokeStatic(Test1.class, "svalue2"); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + Whitebox.invokeStatic(Test1.class, "throwfunc1"); + }); + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.invokeStatic(Test1.class, "throwfunc2"); + }); + } + + @Test + public void testInvoke() { + Test1 test1 = newTest(); + Assert.assertEquals(1, Whitebox.invoke(test1.getClass(), + "value", test1)); + Assert.assertEquals(3, Whitebox.invoke(test1.getClass(), + "addValue", test1, 2)); + Assert.assertEquals(2f, Whitebox.invoke(test1, "test2", "value")); + Assert.assertEquals(2, Whitebox.invoke(test1, "test2", + new Class[]{Object.class}, + "value", 2)); + Assert.assertEquals(3, Whitebox.invoke(test1, "test4", "addValue", 2)); + Assert.assertEquals(4, Whitebox.invoke(test1, "test4", "value")); + + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.invoke(test1.getClass(), "value2", test1); + }); + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.invoke(test1, "test22", "value"); + }); + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.invoke(test1, "test2", "value", 2); + }); + Assert.assertThrows(RuntimeException.class, () -> { + Whitebox.invoke(test1.getClass(), "addValue", test1, 2.0); + }); + } + + private static Test1 newTest() { + Test1 test1 = new Test1(); + test1.test2 = new Test2(); + test1.test2.test3 = new Test3(); + test1.test4 = new TestSubClass(); + return test1; + } + + @SuppressWarnings("unused") + private static class Test1 { + + private static int staticValue = 1; + + private int ivalue = 1; + private final int finalValue = 1; + + private Test2 test2; + private TestSubClass test4; + + private int value() { + return this.ivalue; + } + + private int addValue(int i) { + return this.ivalue + i; + } + + private static int svalue() { + return 1; + } + + private static int svalue(int i) { + return i; + } + + private static T svalue(T o) { + return o; + } + + private static int throwfunc1() { + throw new IllegalArgumentException("fake runtime exception"); + } + + private static int throwfunc2() throws Exception { + throw new Exception("fake exception"); + } + } + + @SuppressWarnings("unused") + private static class Test2 { + + private static int staticValue = 2; + private final float finalValue = 2f; + private Test3 test3; + + private float value() { + return this.finalValue; + } + + private T value(T o) { + return o; + } + } + + @SuppressWarnings("unused") + private static class Test3 { + + private String str = "3"; + + private String value() { + return this.str; + } + } + + @SuppressWarnings("unused") + private static class TestSubClass extends Test1 { + + private int value() { + return 4; + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/BaseUnitTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/BaseUnitTest.java new file mode 100644 index 0000000000..6b9ffcc869 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/BaseUnitTest.java @@ -0,0 +1,71 @@ +/* + * 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.unit; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.apache.commons.io.FileUtils; +import org.apache.hugegraph.util.ExceptionUtil; +import org.apache.hugegraph.util.TimeUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +public class BaseUnitTest { + + @BeforeClass + public static void init() { + // pass + } + + @AfterClass + public static void clear() throws Exception { + // pass + } + + protected static void runWithThreads(int threads, Runnable task) { + ExecutorService executor = Executors.newFixedThreadPool(threads); + List> futures = new ArrayList<>(); + for (int i = 0; i < threads; i++) { + futures.add(executor.submit(task)); + } + for (Future future : futures) { + ExceptionUtil.futureGet(future); + } + } + + protected static void waitTillNext(long seconds) { + TimeUtil.tillNextMillis(TimeUtil.timeGen() + seconds * 1000); + } + + public static void downloadFileByUrl(String url, String destPath) { + int connectTimeout = 5000; + int readTimeout = 5000; + try { + FileUtils.copyURLToFile(new URL(url), new File(destPath), connectTimeout, readTimeout); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java new file mode 100644 index 0000000000..80095d1ccc --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java @@ -0,0 +1,127 @@ +/* + * 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.unit; + +import org.apache.hugegraph.testutil.AssertTest; +import org.apache.hugegraph.testutil.WhiteboxTest; +import org.apache.hugegraph.unit.config.HugeConfigTest; +import org.apache.hugegraph.unit.config.OptionSpaceTest; +import org.apache.hugegraph.unit.event.EventHubTest; +import org.apache.hugegraph.unit.rest.AbstractRestClientTest; +import org.apache.hugegraph.unit.version.VersionTest; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +import org.apache.hugegraph.unit.concurrent.AtomicLockTest; +import org.apache.hugegraph.unit.concurrent.BarrierEventTest; +import org.apache.hugegraph.unit.concurrent.KeyLockTest; +import org.apache.hugegraph.unit.concurrent.LockGroupTest; +import org.apache.hugegraph.unit.concurrent.LockManagerTest; +import org.apache.hugegraph.unit.concurrent.PausableScheduledThreadPoolTest; +import org.apache.hugegraph.unit.concurrent.RowLockTest; +import org.apache.hugegraph.unit.date.SafeDateFormatTest; +import org.apache.hugegraph.unit.iterator.BatchMapperIteratorTest; +import org.apache.hugegraph.unit.iterator.ExtendableIteratorTest; +import org.apache.hugegraph.unit.iterator.FilterIteratorTest; +import org.apache.hugegraph.unit.iterator.FlatMapperFilterIteratorTest; +import org.apache.hugegraph.unit.iterator.FlatMapperIteratorTest; +import org.apache.hugegraph.unit.iterator.LimitIteratorTest; +import org.apache.hugegraph.unit.iterator.ListIteratorTest; +import org.apache.hugegraph.unit.iterator.MapperIteratorTest; +import org.apache.hugegraph.unit.license.LicenseExtraParamTest; +import org.apache.hugegraph.unit.license.LicenseCreateParamTest; +import org.apache.hugegraph.unit.license.LicenseInstallParamTest; +import org.apache.hugegraph.unit.license.LicenseParamsTest; +import org.apache.hugegraph.unit.license.MachineInfoTest; +import org.apache.hugegraph.unit.perf.PerfUtilTest; +import org.apache.hugegraph.unit.perf.StopwatchTest; +import org.apache.hugegraph.unit.rest.RestClientTest; +import org.apache.hugegraph.unit.rest.RestResultTest; +import org.apache.hugegraph.unit.util.BytesTest; +import org.apache.hugegraph.unit.util.CollectionUtilTest; +import org.apache.hugegraph.unit.util.DateUtilTest; +import org.apache.hugegraph.unit.util.EcheckTest; +import org.apache.hugegraph.unit.util.HashUtilTest; +import org.apache.hugegraph.unit.util.InsertionOrderUtilTest; +import org.apache.hugegraph.unit.util.LogTest; +import org.apache.hugegraph.unit.util.LongEncodingTest; +import org.apache.hugegraph.unit.util.NumericUtilTest; +import org.apache.hugegraph.unit.util.OrderLimitMapTest; +import org.apache.hugegraph.unit.util.ReflectionUtilTest; +import org.apache.hugegraph.unit.util.StringUtilTest; +import org.apache.hugegraph.unit.util.TimeUtilTest; +import org.apache.hugegraph.unit.util.UnitUtilTest; +import org.apache.hugegraph.unit.util.VersionUtilTest; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + LockManagerTest.class, + LockGroupTest.class, + AtomicLockTest.class, + KeyLockTest.class, + RowLockTest.class, + PausableScheduledThreadPoolTest.class, + + HugeConfigTest.class, + OptionSpaceTest.class, + SafeDateFormatTest.class, + BarrierEventTest.class, + EventHubTest.class, + PerfUtilTest.class, + StopwatchTest.class, + AbstractRestClientTest.class, + RestClientTest.class, + RestResultTest.class, + VersionTest.class, + + ExtendableIteratorTest.class, + FilterIteratorTest.class, + LimitIteratorTest.class, + MapperIteratorTest.class, + FlatMapperIteratorTest.class, + FlatMapperFilterIteratorTest.class, + ListIteratorTest.class, + BatchMapperIteratorTest.class, + + BytesTest.class, + CollectionUtilTest.class, + EcheckTest.class, + HashUtilTest.class, + InsertionOrderUtilTest.class, + LogTest.class, + NumericUtilTest.class, + ReflectionUtilTest.class, + StringUtilTest.class, + TimeUtilTest.class, + VersionUtilTest.class, + LongEncodingTest.class, + OrderLimitMapTest.class, + DateUtilTest.class, + UnitUtilTest.class, + + LicenseExtraParamTest.class, + LicenseCreateParamTest.class, + LicenseInstallParamTest.class, + LicenseParamsTest.class, + MachineInfoTest.class, + + AssertTest.class, + WhiteboxTest.class +}) +public class UnitTestSuite { +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/AtomicLockTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/AtomicLockTest.java new file mode 100644 index 0000000000..1b2807aa30 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/AtomicLockTest.java @@ -0,0 +1,62 @@ +/* + * 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.unit.concurrent; + +import org.junit.Test; + +import org.apache.hugegraph.concurrent.AtomicLock; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; + +public class AtomicLockTest extends BaseUnitTest { + + @Test + public void testLockUnlock() { + AtomicLock lock = new AtomicLock("lock"); + Assert.assertEquals("lock", lock.name()); + + Assert.assertTrue(lock.lock(0)); + try { + Assert.assertFalse(lock.lock(1)); + // lock in other threads + runWithThreads(2, () -> { + Assert.assertFalse(lock.tryLock()); + }); + lock.unlock(); + } finally { + lock.unlock(); + // unlock multi times is OK + lock.unlock(); + lock.unlock(); + } + + Assert.assertThrows(RuntimeException.class, () -> { + lock.lock(-1); + }, e -> { + Assert.assertContains("Locking retry times should be in [0, 10], " + + "but got -1", e.getMessage()); + }); + + Assert.assertThrows(RuntimeException.class, () -> { + lock.lock(11); + }, e -> { + Assert.assertContains("Locking retry times should be in [0, 10], " + + "but got 11", e.getMessage()); + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/BarrierEventTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/BarrierEventTest.java new file mode 100644 index 0000000000..254f3eb3de --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/BarrierEventTest.java @@ -0,0 +1,288 @@ +/* + * 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.unit.concurrent; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.Test; + +import org.apache.hugegraph.concurrent.BarrierEvent; +import org.apache.hugegraph.testutil.Assert; + +public class BarrierEventTest { + + private static final int WAIT_THREADS_COUNT = 10; + + @Test(timeout = 5000) + public void testAWait() throws InterruptedException { + BarrierEvent barrierEvent = new BarrierEvent(); + AtomicInteger result = new AtomicInteger(0); + CountDownLatch latch = new CountDownLatch(2); + Thread awaitThread = new Thread(() -> { + try { + barrierEvent.await(); + result.incrementAndGet(); + } catch (InterruptedException e) { + // Do nothing. + } finally { + latch.countDown(); + } + }); + awaitThread.start(); + Thread signalThread = new Thread(() -> { + barrierEvent.signalAll(); + latch.countDown(); + }); + signalThread.start(); + latch.await(); + Assert.assertEquals(1, result.get()); + } + + @Test + public void testAWaitWithTimeout() throws InterruptedException { + BarrierEvent barrierEvent = new BarrierEvent(); + boolean signaled = barrierEvent.await(1L); + Assert.assertFalse(signaled); + } + + @Test + public void testReset() throws InterruptedException { + BarrierEvent barrierEvent = new BarrierEvent(); + boolean signaled = barrierEvent.await(1L); + Assert.assertFalse(signaled); + barrierEvent.signal(); + signaled = barrierEvent.await(1L); + Assert.assertTrue(signaled); + barrierEvent.reset(); + signaled = barrierEvent.await(1L); + Assert.assertFalse(signaled); + } + + @Test + public void testSignal() throws InterruptedException { + BarrierEvent barrierEvent = new BarrierEvent(); + boolean signaled = barrierEvent.await(1L); + Assert.assertFalse(signaled); + barrierEvent.signal(); + signaled = barrierEvent.await(1L); + Assert.assertTrue(signaled); + } + + @Test + public void testSignalByMultiThreadWithSignalFirst() + throws InterruptedException { + BarrierEvent barrierEvent = new BarrierEvent(); + AtomicInteger eventCount = new AtomicInteger(0); + AtomicInteger waitThreadInterruptedCount = new AtomicInteger(0); + ExecutorService executorService = + Executors.newFixedThreadPool(WAIT_THREADS_COUNT + 1); + CountDownLatch waitLatch = new CountDownLatch(WAIT_THREADS_COUNT); + CountDownLatch signalLatch = new CountDownLatch(1); + for (int i = 0; i < WAIT_THREADS_COUNT; i++) { + executorService.submit(() -> { + try { + signalLatch.await(); + barrierEvent.await(); + eventCount.incrementAndGet(); + } catch (InterruptedException e) { + waitThreadInterruptedCount.incrementAndGet(); + } finally { + waitLatch.countDown(); + } + }); + } + + executorService.submit(() -> { + barrierEvent.signal(); + signalLatch.countDown(); + }); + + executorService.shutdown(); + executorService.awaitTermination(2L, TimeUnit.SECONDS); + waitLatch.await(); + Assert.assertEquals(10, eventCount.get()); + Assert.assertEquals(0, waitThreadInterruptedCount.get()); + } + + @Test + public void testSignalByMultiThreadWithSignalLast() + throws InterruptedException { + BarrierEvent barrierEvent = new BarrierEvent(); + AtomicInteger eventCount = new AtomicInteger(0); + AtomicInteger waitThreadInterruptedCount = new AtomicInteger(0); + AtomicInteger signalThreadInterruptedCount = new AtomicInteger(0); + ExecutorService executorService = + Executors.newFixedThreadPool(WAIT_THREADS_COUNT + 1); + CountDownLatch waitLatch = new CountDownLatch(WAIT_THREADS_COUNT); + CountDownLatch signalLatch = new CountDownLatch(1); + for (int i = 0; i < WAIT_THREADS_COUNT; i++) { + executorService.submit(() -> { + try { + waitLatch.countDown(); + barrierEvent.await(); + eventCount.incrementAndGet(); + } catch (InterruptedException e) { + waitThreadInterruptedCount.incrementAndGet(); + } + }); + } + + executorService.submit(() -> { + try { + waitLatch.await(); + } catch (InterruptedException e) { + signalThreadInterruptedCount.incrementAndGet(); + } + barrierEvent.signal(); + signalLatch.countDown(); + }); + signalLatch.await(); + executorService.shutdownNow(); + executorService.awaitTermination(1L, TimeUnit.SECONDS); + Assert.assertEquals(1, eventCount.get()); + Assert.assertEquals(WAIT_THREADS_COUNT - 1, + waitThreadInterruptedCount.get()); + Assert.assertEquals(0, signalThreadInterruptedCount.get()); + } + + @Test + public void testSignalAll() throws InterruptedException { + BarrierEvent barrierEvent = new BarrierEvent(); + boolean signaled = barrierEvent.await(1L); + Assert.assertFalse(signaled); + barrierEvent.signalAll(); + signaled = barrierEvent.await(1L); + Assert.assertTrue(signaled); + } + + @Test + public void testSignalAllByMultiThreadWithSignalFirst() + throws InterruptedException { + BarrierEvent barrierEvent = new BarrierEvent(); + AtomicInteger eventCount = new AtomicInteger(0); + AtomicInteger waitThreadInterruptedCount = new AtomicInteger(0); + ExecutorService executorService = + Executors.newFixedThreadPool(WAIT_THREADS_COUNT + 1); + CountDownLatch waitLatch = new CountDownLatch(WAIT_THREADS_COUNT); + CountDownLatch signalLatch = new CountDownLatch(1); + for (int i = 0; i < WAIT_THREADS_COUNT; i++) { + executorService.submit(() -> { + try { + signalLatch.await(); + waitLatch.countDown(); + barrierEvent.await(); + eventCount.incrementAndGet(); + } catch (InterruptedException e) { + waitThreadInterruptedCount.incrementAndGet(); + } + }); + } + + executorService.submit(() -> { + barrierEvent.signalAll(); + signalLatch.countDown(); + }); + + executorService.shutdown(); + executorService.awaitTermination(1L, TimeUnit.SECONDS); + Assert.assertEquals(10, eventCount.get()); + Assert.assertEquals(0, waitThreadInterruptedCount.get()); + } + + @Test + public void testSignalAllByMultiThreadWithSignalLast() + throws InterruptedException { + BarrierEvent barrierEvent = new BarrierEvent(); + AtomicInteger eventCount = new AtomicInteger(0); + AtomicInteger waitThreadInterruptedCount = new AtomicInteger(0); + AtomicInteger signalThreadInterruptedCount = new AtomicInteger(0); + ExecutorService executorService = + Executors.newFixedThreadPool(WAIT_THREADS_COUNT + 1); + CountDownLatch waitLatch = new CountDownLatch(WAIT_THREADS_COUNT); + CountDownLatch signalLatch = new CountDownLatch(1); + for (int i = 0; i < WAIT_THREADS_COUNT; i++) { + executorService.submit(() -> { + try { + waitLatch.countDown(); + barrierEvent.await(); + eventCount.incrementAndGet(); + } catch (InterruptedException e) { + waitThreadInterruptedCount.incrementAndGet(); + } + }); + } + + executorService.submit(() -> { + try { + waitLatch.await(); + } catch (InterruptedException e) { + signalThreadInterruptedCount.incrementAndGet(); + } + barrierEvent.signalAll(); + signalLatch.countDown(); + }); + signalLatch.await(); + executorService.shutdown(); + executorService.awaitTermination(1L, TimeUnit.SECONDS); + Assert.assertEquals(WAIT_THREADS_COUNT, eventCount.get()); + Assert.assertEquals(0, waitThreadInterruptedCount.get()); + Assert.assertEquals(0, signalThreadInterruptedCount.get()); + } + + @Test + public void testSignalAllByMultiThreadWithSignalAwaitConcurrent() + throws InterruptedException { + BarrierEvent barrierEvent = new BarrierEvent(); + AtomicInteger eventCount = new AtomicInteger(0); + AtomicInteger waitThreadInterruptedCount = new AtomicInteger(0); + AtomicInteger signalThreadInterruptedCount = new AtomicInteger(0); + ExecutorService executorService = + Executors.newFixedThreadPool(WAIT_THREADS_COUNT + 1); + CountDownLatch syncLatch = new CountDownLatch(1); + for (int i = 0; i < WAIT_THREADS_COUNT; i++) { + executorService.submit(() -> { + try { + syncLatch.await(); + barrierEvent.await(); + eventCount.incrementAndGet(); + } catch (InterruptedException e) { + waitThreadInterruptedCount.incrementAndGet(); + } + }); + } + + executorService.submit(() -> { + try { + syncLatch.await(); + } catch (InterruptedException e) { + signalThreadInterruptedCount.incrementAndGet(); + } + barrierEvent.signalAll(); + }); + syncLatch.countDown(); + executorService.shutdown(); + executorService.awaitTermination(1L, TimeUnit.SECONDS); + Assert.assertEquals(WAIT_THREADS_COUNT, eventCount.get()); + Assert.assertEquals(0, waitThreadInterruptedCount.get()); + Assert.assertEquals(0, signalThreadInterruptedCount.get()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/KeyLockTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/KeyLockTest.java new file mode 100644 index 0000000000..3f142be764 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/KeyLockTest.java @@ -0,0 +1,124 @@ +/* + * 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.unit.concurrent; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.locks.Lock; + +import org.junit.Test; + +import org.apache.hugegraph.concurrent.KeyLock; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; + +public class KeyLockTest extends BaseUnitTest { + + @Test + public void testLockUnlock() { + KeyLock locks = new KeyLock(); + + locks.lock("1"); + try { + // lock again is OK + locks.lock("1"); + // lock in other threads + runWithThreads(1, () -> { + locks.lock("2"); + }); + locks.unlock("1"); + } finally { + locks.unlock("1"); + } + + Assert.assertThrows(IllegalMonitorStateException.class, () -> { + locks.unlock("2"); + }); + + Assert.assertThrows(IllegalMonitorStateException.class, () -> { + locks.unlock("3"); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + locks.lock(null); + }, e -> { + Assert.assertContains("Lock key can't be null", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + locks.unlock(null); + }, e -> { + Assert.assertContains("Unlock key can't be null", e.getMessage()); + }); + } + + @Test + public void testLockUnlockAll() { + KeyLock locks = new KeyLock(); + + List ls = locks.lockAll("1", 2); + locks.unlockAll(ls); + + runWithThreads(1, () -> { + List ls2 = locks.lockAll("1", 3); + locks.unlockAll(ls2); + }); + + List ls3 = locks.lockAll("1", 2, 3); + locks.unlockAll(ls3); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + locks.lockAll("1", null); + }, e -> { + Assert.assertContains("Lock key can't be null", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + locks.lockAll(null, "1"); + }, e -> { + Assert.assertContains("Lock key can't be null", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + locks.lockAll(Arrays.asList("1", null, 2).toArray()); + }, e -> { + Assert.assertContains("Lock key can't be null", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + locks.lockAll(Collections.emptyList().toArray()); + }, e -> { + Assert.assertContains("Lock keys can't be null or empty", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + locks.lockAll((Object[]) null); + }, e -> { + Assert.assertContains("Lock keys can't be null or empty", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + locks.unlockAll(null); + }, e -> { + Assert.assertContains("Unlock locks can't be null", e.getMessage()); + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/LockGroupTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/LockGroupTest.java new file mode 100644 index 0000000000..961fdde7e8 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/LockGroupTest.java @@ -0,0 +1,106 @@ +/* + * 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.unit.concurrent; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.junit.Test; + +import org.apache.hugegraph.concurrent.AtomicLock; +import org.apache.hugegraph.concurrent.KeyLock; +import org.apache.hugegraph.concurrent.LockGroup; +import org.apache.hugegraph.concurrent.RowLock; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; + +public class LockGroupTest extends BaseUnitTest { + + private static final String GROUP = "LockGroupTest-test-group"; + + private final LockGroup group = new LockGroup(GROUP); + + @Test + public void testLock() { + Lock lock = this.group.lock("lock"); + Assert.assertTrue(lock instanceof ReentrantLock); + Lock lock1 = this.group.lock("lock"); + Assert.assertSame(lock, lock1); + + lock1.lock(); + try { + // lock again is OK + lock1.lock(); + // lock in other threads + runWithThreads(2, () -> { + Assert.assertFalse(lock1.tryLock()); + }); + lock1.unlock(); + } finally { + lock1.unlock(); + } + } + + @Test + public void testAtomicLock() { + AtomicLock lock = this.group.atomicLock("lock"); + Assert.assertNotNull(lock); + AtomicLock lock1 = this.group.atomicLock("lock"); + Assert.assertSame(lock, lock1); + Assert.assertEquals("lock", lock1.name()); + } + + @Test + public void testReadWriteLock() { + ReadWriteLock lock = this.group.readWriteLock("lock"); + Assert.assertTrue(lock instanceof ReentrantReadWriteLock); + ReadWriteLock lock1 = this.group.readWriteLock("lock"); + Assert.assertSame(lock, lock1); + } + + @Test + public void testKeyLock() { + KeyLock lock = this.group.keyLock("lock"); + Assert.assertNotNull(lock); + KeyLock lock1 = this.group.keyLock("lock"); + Assert.assertSame(lock, lock1); + } + + @Test + public void testKeyLockWithSize() { + KeyLock lock = this.group.keyLock("lock", 10); + Assert.assertNotNull(lock); + KeyLock lock1 = this.group.keyLock("lock"); + Assert.assertSame(lock, lock1); + } + + @Test + public void testRowLock() { + RowLock lock = this.group.rowLock("lock"); + Assert.assertNotNull(lock); + RowLock lock1 = this.group.rowLock("lock"); + Assert.assertSame(lock, lock1); + } + + @Test + public void testName() { + Assert.assertEquals(GROUP, this.group.name()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/LockManagerTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/LockManagerTest.java new file mode 100644 index 0000000000..e0efa80645 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/LockManagerTest.java @@ -0,0 +1,125 @@ +/* + * 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.unit.concurrent; + +import org.junit.After; +import org.junit.Test; + +import org.apache.hugegraph.concurrent.LockGroup; +import org.apache.hugegraph.concurrent.LockManager; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; + +public class LockManagerTest extends BaseUnitTest { + + private static final String GROUP = "LockManagerTest-test-group"; + private static final String GROUP2 = GROUP + 2; + + @After + public void teardown() { + LockManager manager = LockManager.instance(); + + if (manager.exists(GROUP)) { + manager.destroy(GROUP); + } + + if (manager.exists(GROUP2)) { + manager.destroy(GROUP2); + } + } + + @Test + public void testCreate() { + LockManager manager = LockManager.instance(); + + LockGroup lockGroup = manager.create(GROUP); + Assert.assertNotNull(lockGroup); + Assert.assertEquals(GROUP, lockGroup.name()); + Assert.assertTrue(manager.exists(GROUP)); + + Assert.assertFalse(manager.exists(GROUP2)); + LockGroup lockGroup2 = manager.create(GROUP2); + Assert.assertNotNull(lockGroup2); + Assert.assertEquals(GROUP2, lockGroup2.name()); + Assert.assertTrue(manager.exists(GROUP2)); + + Assert.assertThrows(RuntimeException.class, () -> { + manager.create(GROUP); + }, e -> { + Assert.assertContains("LockGroup 'LockManagerTest-test-group' " + + "already exists", e.getMessage()); + }); + } + + @Test + public void testGet() { + LockManager manager = LockManager.instance(); + + LockGroup lockGroup = manager.create(GROUP); + LockGroup lockGroup2 = manager.create(GROUP2); + + Assert.assertSame(lockGroup, manager.get(GROUP)); + Assert.assertSame(lockGroup2, manager.get(GROUP2)); + Assert.assertSame(lockGroup, manager.get(GROUP)); + Assert.assertSame(lockGroup2, manager.get(GROUP2)); + + Assert.assertThrows(RuntimeException.class, () -> { + manager.get("fake-lock-group"); + }, e -> { + Assert.assertContains("LockGroup 'fake-lock-group' " + + "does not exists", e.getMessage()); + }); + } + + @Test + public void testDestroy() { + LockManager manager = LockManager.instance(); + + LockGroup lockGroup = manager.create(GROUP); + LockGroup lockGroup2 = manager.create(GROUP2); + + Assert.assertTrue(manager.exists(GROUP)); + Assert.assertTrue(manager.exists(GROUP2)); + Assert.assertSame(lockGroup, manager.get(GROUP)); + Assert.assertSame(lockGroup2, manager.get(GROUP2)); + + manager.destroy(GROUP); + Assert.assertFalse(manager.exists(GROUP)); + Assert.assertTrue(manager.exists(GROUP2)); + Assert.assertThrows(RuntimeException.class, () -> { + manager.get(GROUP); + }, e -> { + Assert.assertContains("does not exists", e.getMessage()); + }); + Assert.assertSame(lockGroup2, manager.get(GROUP2)); + + manager.destroy(GROUP2); + Assert.assertFalse(manager.exists(GROUP)); + Assert.assertFalse(manager.exists(GROUP2)); + Assert.assertThrows(RuntimeException.class, () -> { + manager.get(GROUP); + }, e -> { + Assert.assertContains("does not exists", e.getMessage()); + }); + Assert.assertThrows(RuntimeException.class, () -> { + manager.get(GROUP2); + }, e -> { + Assert.assertContains("does not exists", e.getMessage()); + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/PausableScheduledThreadPoolTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/PausableScheduledThreadPoolTest.java new file mode 100644 index 0000000000..c10b3b8756 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/PausableScheduledThreadPoolTest.java @@ -0,0 +1,93 @@ +/* + * 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.unit.concurrent; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.hugegraph.util.ExecutorUtil; +import org.junit.Assert; +import org.junit.Test; + +import org.apache.hugegraph.concurrent.PausableScheduledThreadPool; + +public class PausableScheduledThreadPoolTest { + + @Test + public void testScheduleWithFixedDelay() throws InterruptedException { + PausableScheduledThreadPool executor = + ExecutorUtil.newPausableScheduledThreadPool("test"); + long period = 500L; + AtomicInteger counter = new AtomicInteger(0); + executor.scheduleWithFixedDelay(() -> { + System.out.println("counter: " + counter.incrementAndGet()); + }, period, period, TimeUnit.MILLISECONDS); + + Thread.sleep((long) (2.1 * period)); + Assert.assertEquals(2, counter.get()); + + // pause + executor.pauseSchedule(); + Thread.sleep(period); + Assert.assertEquals(2, counter.get()); + + // resume + executor.resumeSchedule(); + Thread.sleep((long) (0.5 * period)); + Assert.assertEquals(3, counter.get()); + + Thread.sleep((long) (0.6 * period)); + Assert.assertEquals(4, counter.get()); + + // pause again + executor.pauseSchedule(); + + executor.shutdown(); + executor.awaitTermination(3L, TimeUnit.SECONDS); + } + + @Test + public void testScheduleWithFixedRate() throws InterruptedException { + PausableScheduledThreadPool executor = + ExecutorUtil.newPausableScheduledThreadPool(2, "test"); + long period = 500L; + AtomicInteger counter = new AtomicInteger(0); + executor.scheduleAtFixedRate(() -> { + System.out.println("counter: " + counter.incrementAndGet()); + }, period, period, TimeUnit.MILLISECONDS); + + Thread.sleep((long) (2.1 * period)); + Assert.assertEquals(2, counter.get()); + + // pause + executor.pauseSchedule(); + Thread.sleep(period); + Assert.assertEquals(2, counter.get()); + + // resume + executor.resumeSchedule(); + Thread.sleep((long) (1.1 * period)); + Assert.assertEquals(4, counter.get()); + + // pause again + executor.pauseSchedule(); + + executor.shutdownNow(); + executor.awaitTermination(3L, TimeUnit.SECONDS); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/RowLockTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/RowLockTest.java new file mode 100644 index 0000000000..b845da46d3 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/concurrent/RowLockTest.java @@ -0,0 +1,159 @@ +/* + * 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.unit.concurrent; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +import org.junit.Test; + +import org.apache.hugegraph.concurrent.RowLock; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import com.google.common.collect.ImmutableSet; + +public class RowLockTest extends BaseUnitTest { + + private static final int THREADS_NUM = 8; + + @Test + public void testRowLock() { + RowLock lock = new RowLock<>(); + // Regular lock and unlock + lock.lock(1); + lock.unlock(1); + + // Lock one lock multiple times + lock.lock(1); + lock.lock(1); + lock.unlock(1); + lock.unlock(1); + + // Unlock one lock multiple times + lock.lock(1); + lock.unlock(1); + lock.unlock(1); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + lock.lock(null); + }, e -> { + Assert.assertContains("Lock key can't be null", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + lock.unlock(null); + }, e -> { + Assert.assertContains("Unlock key can't be null", e.getMessage()); + }); + } + + @Test + public void testRowLockMultiRows() { + RowLock lock = new RowLock<>(); + lock.lockAll(ImmutableSet.of(1, 2, 3)); + lock.unlockAll(ImmutableSet.of(1, 2, 3)); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + lock.lockAll(null); + }, e -> { + Assert.assertContains("Lock keys can't be null", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + lock.unlockAll(null); + }, e -> { + Assert.assertContains("Unlock keys can't be null", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + lock.lockAll(ImmutableSet.of()); + }, e -> { + Assert.assertContains("Lock keys can't be null or empty", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + lock.unlockAll(ImmutableSet.of()); + }, e -> { + Assert.assertContains("Unlock keys can't be null or empty", + e.getMessage()); + }); + } + + @Test + public void testRowLockWithMultiThreads() { + RowLock lock = new RowLock<>(); + Set names = new HashSet<>(THREADS_NUM); + List keys = new ArrayList<>(5); + Random random = new Random(); + for (int i = 0; i < 5; i++) { + keys.add(random.nextInt(THREADS_NUM)); + } + + Assert.assertEquals(0, names.size()); + + runWithThreads(THREADS_NUM, () -> { + lock.lockAll(new HashSet<>(keys)); + names.add(Thread.currentThread().getName()); + lock.unlockAll(new HashSet<>(keys)); + }); + + Assert.assertEquals(THREADS_NUM, names.size()); + } + + @Test + public void testRowLockWithMultiThreadsLockOneKey() { + RowLock lock = new RowLock<>(); + Set names = new HashSet<>(THREADS_NUM); + + Assert.assertEquals(0, names.size()); + + Integer key = 1; + runWithThreads(THREADS_NUM, () -> { + lock.lock(key); + names.add(Thread.currentThread().getName()); + lock.unlock(key); + }); + + Assert.assertEquals(THREADS_NUM, names.size()); + } + + @Test + public void testRowLockWithMultiThreadsWithRandomKey() { + RowLock lock = new RowLock<>(); + Set names = new HashSet<>(THREADS_NUM); + + Assert.assertEquals(0, names.size()); + + runWithThreads(THREADS_NUM, () -> { + List keys = new ArrayList<>(5); + Random random = new Random(); + for (int i = 0; i < 5; i++) { + keys.add(random.nextInt(THREADS_NUM)); + } + lock.lockAll(new HashSet<>(keys)); + names.add(Thread.currentThread().getName()); + lock.unlockAll(new HashSet<>(keys)); + }); + + Assert.assertEquals(THREADS_NUM, names.size()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/HugeConfigTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/HugeConfigTest.java new file mode 100644 index 0000000000..4cc04cb4d0 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/HugeConfigTest.java @@ -0,0 +1,673 @@ +/* + * 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.unit.config; + +import static org.apache.hugegraph.config.OptionChecker.allowValues; +import static org.apache.hugegraph.config.OptionChecker.disallowEmpty; +import static org.apache.hugegraph.config.OptionChecker.inValues; +import static org.apache.hugegraph.config.OptionChecker.nonNegativeInt; +import static org.apache.hugegraph.config.OptionChecker.positiveInt; +import static org.apache.hugegraph.config.OptionChecker.rangeDouble; +import static org.apache.hugegraph.config.OptionChecker.rangeInt; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.hugegraph.config.ConfigConvOption; +import org.apache.hugegraph.config.ConfigException; +import org.apache.hugegraph.config.ConfigListConvOption; +import org.apache.hugegraph.config.ConfigListOption; +import org.apache.hugegraph.config.ConfigOption; +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.config.OptionHolder; +import org.apache.hugegraph.config.OptionSpace; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.commons.collections.IteratorUtils; +import org.apache.commons.configuration2.AbstractConfiguration; +import org.apache.commons.configuration2.Configuration; +import org.apache.commons.configuration2.MapConfiguration; +import org.apache.commons.configuration2.PropertiesConfiguration; +import org.apache.commons.configuration2.convert.DisabledListDelimiterHandler; +import org.apache.commons.configuration2.ex.ConfigurationException; +import org.apache.commons.configuration2.io.FileHandler; +import org.apache.commons.io.FileUtils; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +public class HugeConfigTest extends BaseUnitTest { + + private static final String PATH = + "src/test/java/org/apache/hugegraph/unit/config/"; + private static final String CONF = PATH + "test.conf"; + + @BeforeClass + public static void init() { + OptionSpace.register("test", TestOptions.class.getName()); + } + + @Test + public void testOptionDataType() { + Assert.assertEquals(String.class, TestOptions.text1.dataType()); + Assert.assertEquals(Integer.class, TestOptions.int1.dataType()); + Assert.assertEquals(Long.class, TestOptions.long1.dataType()); + Assert.assertEquals(Float.class, TestOptions.float1.dataType()); + Assert.assertEquals(Double.class, TestOptions.double1.dataType()); + Assert.assertEquals(Boolean.class, TestOptions.bool.dataType()); + + Assert.assertEquals(Class.class, TestOptions.clazz.dataType()); + + Assert.assertEquals(List.class, TestOptions.list.dataType()); + Assert.assertEquals(List.class, TestOptions.map.dataType()); + + Assert.assertEquals(String.class, TestOptions.weekday.dataType()); + Assert.assertEquals(List.class, TestOptions.weekdays.dataType()); + } + + @Test + public void testOptionDesc() { + Assert.assertEquals("description of group1.text1", + TestOptions.text1.desc()); + Assert.assertEquals("description of group1.text2 sub", + TestSubOptions.text2.desc()); + } + + @Test + public void testOptionRequired() { + Assert.assertFalse(TestOptions.text1.required()); + Assert.assertTrue(TestSubOptions.text2.required()); + } + + @Test + public void testOptionsToString() { + Assert.assertEquals("[String]group1.text1=text1-value", + TestOptions.text1.toString()); + Assert.assertEquals("[Integer]group1.int1=1", + TestOptions.int1.toString()); + Assert.assertEquals("[Long]group1.long1=100", + TestOptions.long1.toString()); + Assert.assertEquals("[Float]group1.float1=100.0", + TestOptions.float1.toString()); + Assert.assertEquals("[Double]group1.double1=100.0", + TestOptions.double1.toString()); + Assert.assertEquals("[Boolean]group1.bool=true", + TestOptions.bool.toString()); + Assert.assertEquals("[Class]group1.class=class java.lang.Object", + TestOptions.clazz.toString()); + Assert.assertEquals("[List]group1.list=[list-value1, list-value2]", + TestOptions.list.toString()); + Assert.assertEquals("[List]group1.map=[key1:value1, key2:value2]", + TestOptions.map.toString()); + + Assert.assertEquals("[String]group1.text1=text1-value", + TestSubOptions.text1.toString()); + Assert.assertEquals("[String]group1.text2=text2-value-override", + TestSubOptions.text2.toString()); + Assert.assertEquals("[String]group1.textsub=textsub-value", + TestSubOptions.textsub.toString()); + } + + @Test + public void testOptionWithError() { + Assert.assertThrows(ConfigException.class, () -> { + new ConfigOption<>( + "group1.text", + "description of group1.text", + disallowEmpty(), + "" + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigOption<>( + "group1.choice", + "description of group1.choice", + allowValues("CHOICE-1", "CHOICE-2", "CHOICE-3"), + "CHOICE-4" + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigListOption<>( + "group1.list", + true, + "description of group1.list", + disallowEmpty(), + String.class, + ImmutableList.of() + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigOption<>( + "group1.int", + "description of group1.int", + positiveInt(), + 0 + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigOption<>( + "group1.int", + "description of group1.int", + nonNegativeInt(), + -1 + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigOption<>( + "group1.long", + "description of group1.long", + rangeInt(1L, 100L), + 0L + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigOption<>( + "group1.long", + "description of group1.long", + rangeInt(1L, 100L), + 101L + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigOption<>( + "group1.double", + "description of group1.double", + rangeDouble(1D, 10D), + 0D + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigOption<>( + "group1.double", + "description of group1.double", + rangeDouble(1D, 10D), + 11D + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigOption<>( + "group1.class", + "description of group1.class", + input -> input != null && input.equals(Long.class), + Integer.class + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigListOption<>( + "group1.list", + "description of list with invalid default values", + disallowEmpty() + ); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + new ConfigListOption<>( + "group1.list", + "description of list with invalid default values", + null + ); + }); + + Assert.assertThrows(ConfigException.class, () -> { + new ConfigListConvOption( + "group1.list_conv", + "description of list_conv with invalid default values", + disallowEmpty(), + s -> WeekDay.valueOf(s) + ); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + new ConfigListConvOption( + "group1.list_conv", + "description of list_conv with invalid default values", + null, + s -> WeekDay.valueOf(s) + ); + }); + } + + @Test + public void testHugeConfig() throws Exception { + Configuration conf = new PropertiesConfiguration(); + Assert.assertEquals(DisabledListDelimiterHandler.INSTANCE, + ((AbstractConfiguration) conf).getListDelimiterHandler()); + + HugeConfig config = new HugeConfig(conf); + + Assert.assertEquals("text1-value", config.get(TestOptions.text1)); + Assert.assertEquals("text2-value", config.get(TestOptions.text2)); + Assert.assertEquals("CHOICE-1", config.get(TestOptions.text3)); + + Assert.assertEquals(1, (int) config.get(TestOptions.int1)); + Assert.assertEquals(10, (int) config.get(TestOptions.int2)); + Assert.assertEquals(10, (int) config.get(TestOptions.int3)); + + Assert.assertEquals(100L, (long) config.get(TestOptions.long1)); + + Assert.assertEquals(100.0f, config.get(TestOptions.float1), 0f); + Assert.assertEquals(100.0f, config.get(TestOptions.double1), 0d); + + Assert.assertEquals(true, config.get(TestOptions.bool)); + + Assert.assertEquals(Object.class, config.get(TestOptions.clazz)); + Assert.assertThrows(ConfigException.class, () -> { + config.setProperty(TestOptions.clazz.name(), + "org.apache.hugegraph.HugeGraph"); + }, e -> { + Assert.assertTrue(e.getCause() instanceof ClassNotFoundException); + }); + + Assert.assertEquals(Arrays.asList("list-value1", "list-value2"), + config.get(TestOptions.list)); + + Assert.assertEquals(ImmutableMap.of("key1", "value1", "key2", "value2"), + config.getMap(TestOptions.map)); + + Assert.assertEquals(WeekDay.WEDNESDAY, config.get(TestOptions.weekday)); + Assert.assertEquals(Arrays.asList(WeekDay.SATURDAY, WeekDay.SUNDAY), + config.get(TestOptions.weekdays)); + + Assert.assertThrows(ConfigException.class, () -> { + new HugeConfig((Configuration) null); + }); + } + + @Test + public void testHugeConfigWithFile() throws Exception { + HugeConfig config = new HugeConfig(CONF); + + Assert.assertEquals("file-text1-value", config.get(TestOptions.text1)); + Assert.assertEquals("file-text2-value", config.get(TestOptions.text2)); + Assert.assertEquals("CHOICE-3", config.get(TestOptions.text3)); + + Assert.assertEquals(2, (int) config.get(TestOptions.int1)); + Assert.assertEquals(0, (int) config.get(TestOptions.int2)); + Assert.assertEquals(1, (int) config.get(TestOptions.int3)); + + Assert.assertEquals(99L, (long) config.get(TestOptions.long1)); + + Assert.assertEquals(66.0f, config.get(TestOptions.float1), 0f); + Assert.assertEquals(66.0f, config.get(TestOptions.double1), 0d); + + Assert.assertEquals(false, config.get(TestOptions.bool)); + + Assert.assertEquals(String.class, config.get(TestOptions.clazz)); + + Assert.assertEquals(Arrays.asList("file-v1", "file-v2", "file-v3"), + config.get(TestOptions.list)); + + Assert.assertEquals(ImmutableMap.of("key1", "value1", "key3", "value3"), + config.getMap(TestOptions.map)); + + Assert.assertEquals(WeekDay.SUNDAY, config.get(TestOptions.weekday)); + Assert.assertEquals(Arrays.asList(WeekDay.SATURDAY, WeekDay.FRIDAY), + config.get(TestOptions.weekdays)); + } + + @Test + public void testHugeConfigWithConfiguration() throws Exception { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + FileHandler fileHandler = new FileHandler(configuration); + fileHandler.load(CONF); + HugeConfig config = new HugeConfig(configuration); + + Assert.assertEquals("file-text1-value", config.get(TestOptions.text1)); + Assert.assertEquals("file-text2-value", config.get(TestOptions.text2)); + Assert.assertEquals("CHOICE-3", config.get(TestOptions.text3)); + } + + @Test + public void testHugeConfigWithOverride() throws Exception { + Configuration conf = new PropertiesConfiguration(); + Assert.assertEquals(DisabledListDelimiterHandler.INSTANCE, + ((AbstractConfiguration) conf).getListDelimiterHandler()); + + HugeConfig config = new HugeConfig(conf); + + Assert.assertEquals("text1-value", config.get(TestSubOptions.text1)); + + Assert.assertEquals("text2-value-override", + config.get(TestSubOptions.text2)); + Assert.assertEquals("textsub-value", + config.get(TestSubOptions.textsub)); + } + + @Test + public void testHugeConfigWithTypeError() { + OptionSpace.register("test-type-error", + TestOptionsWithTypeError.class.getName()); + + Assert.assertThrows(ConfigException.class, () -> { + new HugeConfig(PATH + "test-type-error.conf"); + }); + } + + @Test + public void testHugeConfigWithCheckError() throws Exception { + OptionSpace.register("test-check-error", + TestOptionsWithCheckError.class.getName()); + + Assert.assertThrows(ConfigException.class, () -> { + new HugeConfig(PATH + "test-check-error.conf"); + }); + } + + @Test + public void testHugeConfigWithListOptionError() throws Exception { + OptionSpace.register("test-list-error", + TestOptionsWithListError.class.getName()); + + Assert.assertThrows(IllegalStateException.class, () -> { + new HugeConfig(PATH + "test-list-error.conf"); + }); + } + + @Test + public void testSaveHugeConfig() throws ConfigurationException, + IOException { + HugeConfig config = new HugeConfig(CONF); + Assert.assertEquals("file-text1-value", config.get(TestOptions.text1)); + + File copiedFile = new File("copied.conf"); + config.save(copiedFile); + Assert.assertTrue(copiedFile.exists()); + Assert.assertTrue(copiedFile.length() > 0); + + try { + HugeConfig copiedConfig = new HugeConfig(copiedFile.getPath()); + Assert.assertEquals(IteratorUtils.toList(config.getKeys()), + IteratorUtils.toList(copiedConfig.getKeys())); + Assert.assertEquals(config.get(TestOptions.text1), + copiedConfig.get(TestOptions.text1)); + } finally { + FileUtils.forceDelete(copiedFile); + } + } + + @Test + public void testFromMapConfigurationWithList() { + Map options = new HashMap<>(); + options.put(TestOptions.list.name(), "[a, b]"); + MapConfiguration mapConfiguration = new MapConfiguration(options); + HugeConfig hugeConfig = new HugeConfig(mapConfiguration); + List values = hugeConfig.get(TestOptions.list); + Assert.assertEquals(2, values.size()); + Assert.assertTrue(values.contains("a")); + Assert.assertTrue(values.contains("b")); + } + + public static class TestOptions extends OptionHolder { + + private static volatile TestOptions instance; + + public static synchronized TestOptions instance() { + if (instance == null) { + instance = new TestOptions(); + instance.registerOptions(); + } + return instance; + } + + public static final ConfigOption text1 = + new ConfigOption<>( + "group1.text1", + "description of group1.text1", + disallowEmpty(), + "text1-value" + ); + + public static final ConfigOption text2 = + new ConfigOption<>( + "group1.text2", + "description of group1.text2", + "text2-value" + ); + + public static final ConfigOption text3 = + new ConfigOption<>( + "group1.text3", + "description of group1.text3", + allowValues("CHOICE-1", "CHOICE-2", "CHOICE-3"), + "CHOICE-1" + ); + + public static final ConfigOption int1 = + new ConfigOption<>( + "group1.int1", + "description of group1.int1", + rangeInt(1, 100), + 1 + ); + + public static final ConfigOption int2 = + new ConfigOption<>( + "group1.int2", + "description of group1.int2", + nonNegativeInt(), + 10 + ); + + public static final ConfigOption int3 = + new ConfigOption<>( + "group1.int3", + "description of group1.int3", + positiveInt(), + 10 + ); + + public static final ConfigOption long1 = + new ConfigOption<>( + "group1.long1", + "description of group1.long1", + rangeInt(1L, 100L), + 100L + ); + + public static final ConfigOption float1 = + new ConfigOption<>( + "group1.float1", + "description of group1.float1", + rangeDouble(1.0f, 100.0f), + 100.0f + ); + + public static final ConfigOption double1 = + new ConfigOption<>( + "group1.double1", + "description of group1.double1", + rangeDouble(1.0, 100.0), + 100.0 + ); + + public static final ConfigOption bool = + new ConfigOption<>( + "group1.bool", + "description of group1.bool", + disallowEmpty(), + true + ); + + public static final ConfigOption> clazz = + new ConfigOption<>( + "group1.class", + "description of group1.class", + disallowEmpty(), + Object.class + ); + + public static final ConfigConvOption weekday = + new ConfigConvOption<>( + "group1.weekday", + "description of group1.weekday", + allowValues("SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", + "THURSDAY", "FRIDAY", "SATURDAY"), + WeekDay::valueOf, + "WEDNESDAY" + ); + + public static final ConfigListConvOption weekdays = + new ConfigListConvOption<>( + "group1.weekdays", + "description of group1.weekdays", + inValues("SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", + "THURSDAY", "FRIDAY", "SATURDAY"), + WeekDay::valueOf, + "SATURDAY", "SUNDAY" + ); + + public static final ConfigListOption list = + new ConfigListOption<>( + "group1.list", + "description of group1.list", + disallowEmpty(), + "list-value1", "list-value2" + ); + + public static final ConfigListOption map = + new ConfigListOption<>( + "group1.map", + "description of group1.map", + disallowEmpty(), + "key1:value1", "key2:value2" + ); + } + + public static class TestSubOptions extends TestOptions { + + public static final ConfigOption text2 = + new ConfigOption<>( + "group1.text2", + true, + "description of group1.text2 sub", + disallowEmpty(), + String.class, + "text2-value-override" + ); + + public static final ConfigOption textsub = + new ConfigOption<>( + "group1.textsub", + "description of group1.textsub", + disallowEmpty(), + "textsub-value" + ); + } + + public static class TestOptionsWithTypeError extends OptionHolder { + + private static volatile TestOptionsWithTypeError instance; + + public static synchronized TestOptionsWithTypeError instance() { + if (instance == null) { + instance = new TestOptionsWithTypeError(); + instance.registerOptions(); + } + return instance; + } + + public static final ConfigOption intError = + new ConfigOption<>( + "group1.int_type_error", + "description of group1.int_type_error", + rangeInt(1, 100), + 1 + ); + } + + public static class TestOptionsWithCheckError extends OptionHolder { + + private static volatile TestOptionsWithCheckError instance; + + public static synchronized TestOptionsWithCheckError instance() { + if (instance == null) { + instance = new TestOptionsWithCheckError(); + instance.registerOptions(); + } + return instance; + } + + public static final ConfigOption intError = + new ConfigOption<>( + "group1.int_check_error", + "description of group1.int_check_error", + rangeInt(1, 100), + 1 + ); + } + + public static class TestOptionsWithListError extends OptionHolder { + + private static volatile TestOptionsWithListError instance; + + public static synchronized TestOptionsWithListError instance() { + if (instance == null) { + instance = new TestOptionsWithListError(); + instance.registerOptions(); + } + return instance; + } + + public static final InvalidConfigListOption listError = + new InvalidConfigListOption<>( + "group1.list_for_list_error", + "description of group1.list_for_list_error", + disallowEmpty(), + 1 + ); + + static class InvalidConfigListOption extends ConfigOption> { + + @SuppressWarnings("unchecked") + public InvalidConfigListOption(String name, String desc, + Predicate> pred, + T... values) { + super(name, false, desc, pred, + (Class>) Arrays.asList(values).getClass(), + Arrays.asList(values)); + } + + @Override + protected boolean forList() { + return false; + } + } + } + + public enum WeekDay { + + SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/OptionSpaceTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/OptionSpaceTest.java new file mode 100644 index 0000000000..ab794faf5d --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/OptionSpaceTest.java @@ -0,0 +1,215 @@ +/* + * 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.unit.config; + +import static org.apache.hugegraph.config.OptionChecker.disallowEmpty; + +import org.junit.Test; + +import org.apache.hugegraph.config.OptionSpace; +import org.apache.hugegraph.config.OptionHolder; +import org.apache.hugegraph.config.ConfigException; +import org.apache.hugegraph.config.ConfigOption; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import com.google.common.base.Predicate; + +public class OptionSpaceTest extends BaseUnitTest { + + @Test + public void tesRegister() { + int oldSize = OptionSpace.keys().size(); + + OptionSpace.register("testgroup1", OptionHolder1.class.getName()); + Assert.assertEquals(oldSize + 2, OptionSpace.keys().size()); + Assert.assertTrue(OptionSpace.containKey("testgroup1.text1")); + Assert.assertTrue(OptionSpace.containKey("testgroup1.text2")); + + OptionSpace.register("testgroup1", new OptionHolder1()); + Assert.assertEquals(oldSize + 2, OptionSpace.keys().size()); + Assert.assertTrue(OptionSpace.containKey("testgroup1.text1")); + Assert.assertTrue(OptionSpace.containKey("testgroup1.text2")); + + OptionSpace.register("testgroup2", OptionHolder2.class.getName()); + Assert.assertEquals(oldSize + 4, OptionSpace.keys().size()); + + Assert.assertTrue(OptionSpace.containKey("testgroup1.text1")); + Assert.assertTrue(OptionSpace.containKey("testgroup1.text2")); + Assert.assertTrue(OptionSpace.containKey("testgroup2.text1")); + Assert.assertTrue(OptionSpace.containKey("testgroup2.text2")); + + Assert.assertEquals("text1 value", + OptionSpace.get("testgroup1.text1").defaultValue()); + Assert.assertEquals("text2 value", + OptionSpace.get("testgroup1.text2").defaultValue()); + Assert.assertEquals("text1 value", + OptionSpace.get("testgroup2.text1").defaultValue()); + Assert.assertEquals("text2 value", + OptionSpace.get("testgroup2.text2").defaultValue()); + } + + @Test + public void testRegisterWithError() { + Assert.assertThrows(ConfigException.class, () -> { + OptionSpace.register("test-error", "fake"); + }); + + Assert.assertThrows(ConfigException.class, () -> { + OptionSpace.register("test-error", Exception.class.getName()); + }); + + Assert.assertThrows(ConfigException.class, () -> { + OptionSpace.register("test-error", + OptionHolderWithoutInstance.class.getName()); + }); + + Assert.assertThrows(ConfigException.class, () -> { + OptionSpace.register("test-error", OptionHolderWithNonStaticInstance + .class.getName()); + }); + + Assert.assertThrows(ConfigException.class, () -> { + OptionSpace.register("test-error", + OptionHolderWithInstanceNull.class.getName()); + }); + + Assert.assertThrows(ConfigException.class, () -> { + OptionSpace.register("test-error", + OptionHolderWithInstanceThrow.class.getName()); + }); + + Assert.assertThrows(ConfigException.class, () -> { + OptionSpace.register("test-error", + OptionHolderWithInvalidOption.class.getName()); + }); + } + + public static class OptionHolderWithoutInstance extends OptionHolder { + // no instance() + } + + public static class OptionHolderWithNonStaticInstance extends OptionHolder { + + // not static instance() + public OptionHolderWithNonStaticInstance instance() { + return new OptionHolderWithNonStaticInstance(); + } + } + + public static class OptionHolderWithInstanceNull extends OptionHolder { + + public static OptionHolderWithInstanceNull instance() { + return null; + } + } + + public static class OptionHolderWithInstanceThrow extends OptionHolder { + + public static OptionHolderWithInstanceNull instance() { + throw new RuntimeException("test error"); + } + } + + public static class OptionHolderWithInvalidOption extends OptionHolder { + + public static OptionHolderWithInvalidOption instance() { + return new OptionHolderWithInvalidOption(); + } + + private OptionHolderWithInvalidOption() { + this.registerOptions(); + } + + public static final String fake = "fake"; + + public static final ConfigOption invalid = + new InvalidOption<>( + "group1.text1", + "description of group1.text1", + disallowEmpty(), + "value" + ); + + public static class InvalidOption extends ConfigOption { + + public InvalidOption(String name, String desc, + Predicate pred, T value) { + super(name, desc, pred, value); + } + + @Override + public String name() { + throw new RuntimeException("fake"); + } + } + } + + public static class OptionHolder1 extends OptionHolder { + + public static OptionHolder1 instance() { + return new OptionHolder1(); + } + + OptionHolder1() { + this.registerOptions(); + } + + public static final ConfigOption text1 = + new ConfigOption<>( + "testgroup1.text1", + "description of testgroup1.text1", + disallowEmpty(), + "text1 value" + ); + + public static final ConfigOption text2 = + new ConfigOption<>( + "testgroup1.text2", + "description of testgroup1.text2", + disallowEmpty(), + "text2 value" + ); + } + + public static class OptionHolder2 extends OptionHolder { + + public static OptionHolder2 instance() { + return new OptionHolder2(); + } + + OptionHolder2() { + this.registerOptions(); + } + + public static final ConfigOption text1 = + new ConfigOption<>( + "testgroup2.text1", + "description of testgroup2.text1", + disallowEmpty(), + "text1 value" + ); + + public static final ConfigOption text2 = + new ConfigOption<>( + "testgroup2.text2", + "description of testgroup2.text2", + disallowEmpty(), + "text2 value" + ); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test-check-error.conf b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test-check-error.conf new file mode 100644 index 0000000000..53aec18463 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test-check-error.conf @@ -0,0 +1 @@ +group1.int_check_error=101 diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test-list-error.conf b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test-list-error.conf new file mode 100644 index 0000000000..907b197f44 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test-list-error.conf @@ -0,0 +1,2 @@ +group1.list_for_list_error=[1,2,3] + diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test-type-error.conf b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test-type-error.conf new file mode 100644 index 0000000000..ac70d48913 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test-type-error.conf @@ -0,0 +1 @@ +group1.int_type_error=string diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test.conf b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test.conf new file mode 100644 index 0000000000..9ee10b0a34 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/config/test.conf @@ -0,0 +1,23 @@ +group1.text1=file-text1-value +group1.text2=file-text2-value +group1.text3=CHOICE-3 + +group1.int1=2 +group1.int2=0 +group1.int3=1 +group1.long1=99 + +group1.float1=66 +group1.double1=66 + +group1.bool=false + +group1.class=java.lang.String + +group1.list=[file-v1, file-v2, file-v3] +group1.map=[key1:value1, key3:value3] + +group1.weekday=SUNDAY +group1.weekdays=[SATURDAY, FRIDAY] + +group1.no-used=value diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/date/SafeDateFormatTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/date/SafeDateFormatTest.java new file mode 100644 index 0000000000..30729ebab4 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/date/SafeDateFormatTest.java @@ -0,0 +1,127 @@ +/* + * 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.unit.date; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; +import java.util.concurrent.CountDownLatch; + +import org.apache.hugegraph.date.SafeDateFormat; +import org.junit.Test; + +import org.apache.hugegraph.testutil.Assert; +import com.google.common.collect.ImmutableList; + +public class SafeDateFormatTest { + + @Test + @SuppressWarnings("deprecation") + public void testSafeDateFormatInConcurrency() throws Exception { + SafeDateFormat format = new SafeDateFormat("yyyy-MM-dd"); + List sources = ImmutableList.of( + "2010-01-01", + "2011-02-02", + "2012-03-03", + "2013-04-04", + "2014-05-05", + "2015-06-06", + "2016-07-07", + "2017-08-08", + "2018-09-09", + "2019-10-10" + ); + List dates = new ArrayList<>(sources.size()); + + for (int i = 0; i < sources.size(); i++) { + Date date = format.parse(sources.get(i)); + Assert.assertEquals(2010 + i, 1900 + date.getYear()); + Assert.assertEquals(i, date.getMonth()); + Assert.assertEquals(1 + i, date.getDate()); + dates.add(date); + } + + List exceptions = new ArrayList<>(); + final CountDownLatch latch = new CountDownLatch(1); + int threadCount = 10; + List threads = new ArrayList<>(threadCount); + for (int t = 0; t < threadCount; t++) { + Thread thread = new Thread(() -> { + try { + latch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + for (int i = 0; i < sources.size(); i++) { + try { + Assert.assertEquals(dates.get(i), + format.parse(sources.get(i))); + Assert.assertEquals(sources.get(i), + format.format(dates.get(i))); + } catch (Exception e) { + exceptions.add(e); + } + } + }); + threads.add(thread); + } + + for (Thread thread : threads) { + thread.start(); + } + + latch.countDown(); + + for (Thread thread : threads) { + thread.join(); + } + + Assert.assertTrue(exceptions.isEmpty()); + } + + @Test + public void testTimeZone() throws ParseException { + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + df.setTimeZone(TimeZone.getTimeZone("GMT+10")); + + SafeDateFormat sdf = new SafeDateFormat("yyyy-MM-dd HH:mm:ss"); + sdf.setTimeZone("GMT+10"); + + Assert.assertEquals(df.getTimeZone(), sdf.getTimeZone()); + Assert.assertEquals(df.parse("2019-08-10 00:00:00"), + sdf.parse("2019-08-10 00:00:00")); + Assert.assertEquals("2019-08-10 00:00:00", + sdf.format(sdf.parse("2019-08-10 00:00:00"))); + Assert.assertEquals(df.format(df.parse("2019-08-10 00:00:00")), + sdf.format(sdf.parse("2019-08-10 00:00:00"))); + + sdf.setTimeZone("GMT+11"); + Assert.assertNotEquals(df.getTimeZone(), sdf.getTimeZone()); + Assert.assertNotEquals(df.parse("2019-08-10 00:00:00"), + sdf.parse("2019-08-10 00:00:00")); + Assert.assertEquals("2019-08-10 00:00:00", + sdf.format(sdf.parse("2019-08-10 00:00:00"))); + Assert.assertEquals(df.format(df.parse("2019-08-10 00:00:00")), + sdf.format(sdf.parse("2019-08-10 00:00:00"))); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/event/EventHubTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/event/EventHubTest.java new file mode 100644 index 0000000000..dff0227022 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/event/EventHubTest.java @@ -0,0 +1,462 @@ +/* + * 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.unit.event; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.collect.ImmutableList; + +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.event.Event; +import org.apache.hugegraph.event.EventHub; +import org.apache.hugegraph.event.EventListener; + +public class EventHubTest extends BaseUnitTest { + + private static final int THREADS_NUM = 8; + + private EventHub eventHub = null; + + @BeforeClass + public static void init() { + EventHub.init(THREADS_NUM); + } + + @AfterClass + public static void clear() throws InterruptedException { + EventHub.destroy(30); + } + + @Before + public void setup() { + this.eventHub = new EventHub("test"); + Assert.assertEquals("test", this.eventHub.name()); + } + + @After + public void teardown() { + this.eventHub = null; + } + + private void wait100ms() { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + @Test + public void testEventGetListenerNonResult() { + Assert.assertFalse(this.eventHub.containsListener("not-exist")); + Assert.assertEquals(0, this.eventHub.listeners("not-exist").size()); + } + + @Test + public void testEventAddListener() { + final String event = "event-test"; + + EventListener listener = (Event e) -> null; + + this.eventHub.listen(event, listener); + + Assert.assertTrue(this.eventHub.containsListener(event)); + Assert.assertEquals(1, this.eventHub.listeners(event).size()); + Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); + } + + @Test + public void testEventAddListenerTwice() { + final String event = "event-test"; + + EventListener listener = (Event e) -> null; + + this.eventHub.listen(event, listener); + this.eventHub.listen(event, listener); + + Assert.assertTrue(this.eventHub.containsListener(event)); + Assert.assertEquals(2, this.eventHub.listeners(event).size()); + Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); + Assert.assertEquals(listener, this.eventHub.listeners(event).get(1)); + } + + @Test + public void testEventRemoveListener() { + final String event = "event-test"; + + EventListener listener = (Event e) -> null; + + this.eventHub.listen(event, listener); + + Assert.assertTrue(this.eventHub.containsListener(event)); + Assert.assertEquals(1, this.eventHub.listeners(event).size()); + Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); + + Assert.assertEquals(1, this.eventHub.unlisten(event, listener)); + + Assert.assertFalse(this.eventHub.containsListener(event)); + Assert.assertEquals(0, this.eventHub.listeners(event).size()); + } + + @Test + public void testEventRemoveListenerButNonResult() { + final String event = "event-test"; + + EventListener listener = (Event e) -> null; + + this.eventHub.listen(event, listener); + + Assert.assertTrue(this.eventHub.containsListener(event)); + Assert.assertEquals(1, this.eventHub.listeners(event).size()); + Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); + + Assert.assertEquals(0, this.eventHub.unlisten(event, null)); + Assert.assertEquals(0, this.eventHub.unlisten("event-fake", listener)); + + Assert.assertTrue(this.eventHub.containsListener(event)); + Assert.assertEquals(1, this.eventHub.listeners(event).size()); + Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); + } + + @Test + public void testEventRemoveListenerOfOneInTwo() { + final String event1 = "event-test1"; + final String event2 = "event-test2"; + + EventListener listener = (Event e) -> null; + + this.eventHub.listen(event1, listener); + this.eventHub.listen(event2, listener); + + Assert.assertTrue(this.eventHub.containsListener(event1)); + Assert.assertEquals(1, this.eventHub.listeners(event1).size()); + Assert.assertEquals(listener, this.eventHub.listeners(event1).get(0)); + + Assert.assertTrue(this.eventHub.containsListener(event2)); + Assert.assertEquals(1, this.eventHub.listeners(event2).size()); + Assert.assertEquals(listener, this.eventHub.listeners(event2).get(0)); + + Assert.assertEquals(1, this.eventHub.unlisten(event1, listener)); + + Assert.assertFalse(this.eventHub.containsListener(event1)); + Assert.assertFalse(this.eventHub.containsListener(event1)); + Assert.assertEquals(0, this.eventHub.listeners(event1).size()); + + Assert.assertTrue(this.eventHub.containsListener(event2)); + Assert.assertEquals(1, this.eventHub.listeners(event2).size()); + Assert.assertEquals(listener, this.eventHub.listeners(event2).get(0)); + } + + @Test + public void testEventRemoveListenerByEvent() { + final String event = "event-test"; + + EventListener listener1 = (Event e) -> null; + EventListener listener2 = (Event e) -> null; + + this.eventHub.listen(event, listener1); + this.eventHub.listen(event, listener2); + + Assert.assertTrue(this.eventHub.containsListener(event)); + Assert.assertEquals(2, this.eventHub.listeners(event).size()); + Assert.assertEquals(listener1, this.eventHub.listeners(event).get(0)); + Assert.assertEquals(listener2, this.eventHub.listeners(event).get(1)); + + Assert.assertEquals(2, this.eventHub.unlisten(event).size()); + + Assert.assertFalse(this.eventHub.containsListener(event)); + Assert.assertEquals(0, this.eventHub.listeners(event).size()); + } + + @Test + public void testEventRemoveListenerByEventButNonResult() { + final String event = "event-test"; + + EventListener listener1 = (Event e) -> null; + EventListener listener2 = (Event e) -> null; + + this.eventHub.listen(event, listener1); + this.eventHub.listen(event, listener2); + + Assert.assertTrue(this.eventHub.containsListener(event)); + Assert.assertEquals(2, this.eventHub.listeners(event).size()); + Assert.assertEquals(listener1, this.eventHub.listeners(event).get(0)); + Assert.assertEquals(listener2, this.eventHub.listeners(event).get(1)); + + Assert.assertEquals(0, this.eventHub.unlisten("event-fake").size()); + + Assert.assertEquals(2, this.eventHub.listeners(event).size()); + } + + @Test + public void testEventRemoveListenerByEventOf2SameListener() { + final String event = "event-test"; + + EventListener listener = (Event e) -> null; + + this.eventHub.listen(event, listener); + this.eventHub.listen(event, listener); + + Assert.assertTrue(this.eventHub.containsListener(event)); + Assert.assertEquals(2, this.eventHub.listeners(event).size()); + Assert.assertEquals(listener, this.eventHub.listeners(event).get(0)); + + Assert.assertEquals(2, this.eventHub.unlisten(event, listener)); + + Assert.assertFalse(this.eventHub.containsListener(event)); + Assert.assertEquals(0, this.eventHub.listeners(event).size()); + } + + @Test + public void testEventCallWithoutArg() { + final String call = "event-call"; + + this.eventHub.listen(call, event -> { + Assert.assertEquals(call, event.name()); + Assert.assertEquals(0, event.args().length); + return "fake-event-result"; + }); + + Assert.assertEquals("fake-event-result", this.eventHub.call(call)); + } + + @Test + public void testEventCallWithArg1() { + final String call = "event-call"; + + this.eventHub.listen(call, event -> { + Assert.assertEquals(call, event.name()); + + event.checkArgs(Float.class); + + Object[] args = event.args(); + Assert.assertEquals(1, args.length); + Assert.assertEquals(3.14f, args[0]); + + return "fake-event-result"; + }); + + Assert.assertEquals("fake-event-result", + this.eventHub.call(call, 3.14f)); + } + + @Test + public void testEventCallWithArg2() { + final String call = "event-call"; + + this.eventHub.listen(call, event -> { + Assert.assertEquals(call, event.name()); + + event.checkArgs(String.class, Integer.class); + + Object[] args = event.args(); + Assert.assertEquals(2, args.length); + Assert.assertEquals("fake-arg0", args[0]); + Assert.assertEquals(123, args[1]); + + return "fake-event-result"; + }); + + Assert.assertEquals("fake-event-result", + this.eventHub.call(call, "fake-arg0", 123)); + } + + @Test + public void testEventCallWithArg2ButArgNotMatched() { + final String call = "event-call"; + + this.eventHub.listen(call, event -> { + Assert.assertEquals(call, event.name()); + + event.checkArgs(String.class, Integer.class); + + Object[] args = event.args(); + Assert.assertEquals(2, args.length); + Assert.assertEquals("fake-arg0", args[0]); + Assert.assertEquals(123, args[1]); + + return "fake-event-result"; + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + this.eventHub.call(call, "fake-arg0"); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + this.eventHub.call(call, "fake-arg0", 123, "456"); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + this.eventHub.call(call, 123, "fake-arg0"); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + this.eventHub.call(call, "fake-arg0", 123f); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + this.eventHub.call(call, "fake-arg0", "123"); + }); + } + + @Test + public void testEventNotify() { + final String notify = "event-notify"; + AtomicInteger count = new AtomicInteger(); + + this.eventHub.listen(notify, event -> { + Assert.assertEquals(notify, event.name()); + Assert.assertEquals(0, event.args().length); + count.incrementAndGet(); + return true; + }); + + this.eventHub.notify(notify); + + // Maybe should improve + this.wait100ms(); + + Assert.assertEquals(1, count.get()); + } + + @Test + public void testEventNotifyAny() { + AtomicInteger count = new AtomicInteger(); + + this.eventHub.listen(EventHub.ANY_EVENT, event -> { + Assert.assertTrue(ImmutableList.of("event1", "event2") + .contains(event.name())); + Assert.assertEquals(0, event.args().length); + count.incrementAndGet(); + return true; + }); + + this.eventHub.notify("event1"); + this.eventHub.notify("event2"); + + // Maybe should improve + this.wait100ms(); + + Assert.assertEquals(2, count.get()); + } + + @Test + public void testEventNotifyWithArg2() { + final String notify = "event-notify"; + AtomicInteger count = new AtomicInteger(); + + this.eventHub.listen(notify, event -> { + Assert.assertEquals(notify, event.name()); + + event.checkArgs(String.class, Integer.class); + + Object[] args = event.args(); + Assert.assertEquals("fake-arg0", args[0]); + Assert.assertEquals(123, args[1]); + + count.incrementAndGet(); + return true; + }); + + this.eventHub.notify(notify, "fake-arg0", 123); + + // Maybe should improve + this.wait100ms(); + + Assert.assertEquals(1, count.get()); + } + + @Test + public void testEventNotifyWithMultiThreads() throws InterruptedException { + final String notify = "event-notify"; + + EventListener listener1 = event -> { + Assert.assertEquals(notify, event.name()); + event.checkArgs(Integer.class); + return null; + }; + + EventListener listener2 = event -> { + Assert.assertEquals(notify, event.name()); + + event.checkArgs(Integer.class); + int i = (int) event.args()[0]; + if (i % 10000 == 0) { + System.out.println("On event '" + notify + "': " + i); + } + return null; + }; + + Thread listenerUpdateThread = new Thread(() -> { + // This will cost about 1s + for (int i = 0; i < 10; i++) { + this.eventHub.listen(notify, listener1); + if (!this.eventHub.listeners(notify).contains(listener2)) { + this.eventHub.listen(notify, listener2); + } + + this.wait100ms(); + + if (i % 2 == 0) { + this.eventHub.unlisten(notify); + } else { + this.eventHub.unlisten(notify, listener1); + } + } + }); + listenerUpdateThread.start(); + + runWithThreads(THREADS_NUM, () -> { + // This will cost about 1s ~ 2s + for (int i = 0; i < 10000 * 10; i++) { + this.eventHub.notify(notify, i); + Thread.yield(); + } + }); + + listenerUpdateThread.join(); + } + + @Test + public void testEventCallWithMultiThreads() { + final String call = "event-call"; + + EventListener listener = event -> { + Assert.assertEquals(call, event.name()); + + event.checkArgs(Integer.class); + int i = (int) event.args()[0]; + return i; + }; + + this.eventHub.listen(call, listener); + + runWithThreads(THREADS_NUM, () -> { + for (int i = 0; i < 10000 * 1000; i++) { + Assert.assertEquals(i, this.eventHub.call(call, i)); + } + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/BatchMapperIteratorTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/BatchMapperIteratorTest.java new file mode 100644 index 0000000000..52bc632c0a --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/BatchMapperIteratorTest.java @@ -0,0 +1,337 @@ +/* + * 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.unit.iterator; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; + +import org.junit.Test; + +import org.apache.hugegraph.iterator.BatchMapperIterator; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.unit.iterator.ExtendableIteratorTest.CloseableItor; +import com.google.common.collect.ImmutableList; + +@SuppressWarnings("resource") +public class BatchMapperIteratorTest extends BaseUnitTest { + + private static final Iterator EMPTY = Collections.emptyIterator(); + + private static final List DATA1 = ImmutableList.of(1); + private static final List DATA2 = ImmutableList.of(2, 3); + private static final List DATA3 = ImmutableList.of(4, 5, 6); + + private static final Function, Iterator> MAPPER = + batch -> batch.iterator(); + + @Test + public void testBatchMapper() { + Iterator results; + + results = new BatchMapperIterator<>(1, DATA1.iterator(), MAPPER); + Assert.assertEquals(ImmutableList.of(1), ImmutableList.copyOf(results)); + + results = new BatchMapperIterator<>(1, DATA2.iterator(), MAPPER); + Assert.assertEquals(ImmutableList.of(2, 3), + ImmutableList.copyOf(results)); + + results = new BatchMapperIterator<>(1, DATA3.iterator(), MAPPER); + Assert.assertEquals(ImmutableList.of(4, 5, 6), + ImmutableList.copyOf(results)); + } + + @Test + public void testBatch() { + Iterator results; + + results = new BatchMapperIterator<>(2, DATA2.iterator(), MAPPER); + Assert.assertEquals(ImmutableList.of(2, 3), + ImmutableList.copyOf(results)); + + results = new BatchMapperIterator<>(2, DATA3.iterator(), MAPPER); + Assert.assertEquals(ImmutableList.of(4, 5, 6), + ImmutableList.copyOf(results)); + + results = new BatchMapperIterator<>(3, DATA3.iterator(), MAPPER); + Assert.assertEquals(ImmutableList.of(4, 5, 6), + ImmutableList.copyOf(results)); + + results = new BatchMapperIterator<>(4, DATA3.iterator(), MAPPER); + Assert.assertEquals(ImmutableList.of(4, 5, 6), + ImmutableList.copyOf(results)); + } + + @Test + public void testInvalidBatch() { + Assert.assertThrows(IllegalArgumentException.class, () -> { + new BatchMapperIterator<>(0, DATA1.iterator(), MAPPER); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + new BatchMapperIterator<>(-1, DATA1.iterator(), MAPPER); + }); + } + + @Test + public void testHasNext() { + Iterator results; + + results = new BatchMapperIterator<>(1, EMPTY, MAPPER); + Assert.assertFalse(results.hasNext()); + + results = new BatchMapperIterator<>(1, DATA1.iterator(), MAPPER); + Assert.assertTrue(results.hasNext()); + } + + @Test + public void testHasNextAndNextWithMultiTimes() { + Iterator results; + + results = new BatchMapperIterator<>(1, DATA3.iterator(), MAPPER); + + for (int i = 0; i < 5; i++) { + Assert.assertTrue(results.hasNext()); + } + + for (int i = 0; i < 3; i++) { + results.next(); + } + + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + + Assert.assertThrows(NoSuchElementException.class, results::next); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNext() { + Iterator results; + + results = new BatchMapperIterator<>(1, DATA1.iterator(), MAPPER); + // Call next() without hasNext() + Assert.assertEquals(1, results.next()); + + results = new BatchMapperIterator<>(1, DATA3.iterator(), MAPPER); + Assert.assertEquals(4, results.next()); + Assert.assertEquals(5, results.next()); + Assert.assertEquals(6, results.next()); + + results = new BatchMapperIterator<>(2, DATA3.iterator(), MAPPER); + Assert.assertEquals(4, results.next()); + Assert.assertEquals(5, results.next()); + Assert.assertEquals(6, results.next()); + } + + @Test + public void testNextWithMultiTimes() { + Iterator results; + + results = new BatchMapperIterator<>(1, DATA2.iterator(), MAPPER); + + for (int i = 0; i < 2; i++) { + results.next(); + } + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testMapperWithBatch() { + Iterator results; + + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + Assert.assertEquals(1, batch.size()); + return batch.iterator(); + }); + Assert.assertEquals(4, results.next()); + Assert.assertEquals(5, results.next()); + Assert.assertEquals(6, results.next()); + Assert.assertFalse(results.hasNext()); + + results = new BatchMapperIterator<>(2, DATA3.iterator(), batch -> { + if (batch.size() == 1) { + Assert.assertEquals(6, batch.get(0)); + } else { + Assert.assertEquals(2, batch.size()); + } + return batch.iterator(); + }); + Assert.assertEquals(4, results.next()); + Assert.assertEquals(5, results.next()); + Assert.assertEquals(6, results.next()); + Assert.assertFalse(results.hasNext()); + + results = new BatchMapperIterator<>(3, DATA3.iterator(), batch -> { + Assert.assertEquals(3, batch.size()); + return batch.iterator(); + }); + Assert.assertEquals(4, results.next()); + Assert.assertEquals(5, results.next()); + Assert.assertEquals(6, results.next()); + Assert.assertFalse(results.hasNext()); + + results = new BatchMapperIterator<>(4, DATA3.iterator(), batch -> { + Assert.assertEquals(3, batch.size()); + return batch.iterator(); + }); + Assert.assertEquals(4, results.next()); + Assert.assertEquals(5, results.next()); + Assert.assertEquals(6, results.next()); + Assert.assertFalse(results.hasNext()); + } + + @Test + public void testMapperThenReturn2X() { + Iterator results; + + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + List list = new ArrayList<>(); + for (int i : batch) { + list.add(2 * i); + } + return list.iterator(); + }); + + Assert.assertEquals(8, results.next()); + Assert.assertEquals(10, results.next()); + Assert.assertEquals(12, results.next()); + Assert.assertFalse(results.hasNext()); + } + + @Test + public void testMapperReturnNullThenHasNext() { + Iterator results; + + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + return null; + }); + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + + AtomicInteger count1 = new AtomicInteger(0); + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + if (count1.incrementAndGet() == 1) { + return null; + } + return batch.iterator(); + }); + Assert.assertTrue(results.hasNext()); + Assert.assertEquals(5, results.next()); + Assert.assertEquals(6, results.next()); + Assert.assertFalse(results.hasNext()); + + AtomicInteger count2 = new AtomicInteger(0); + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + if (count2.incrementAndGet() == 2) { + return null; + } + return batch.iterator(); + }); + Assert.assertTrue(results.hasNext()); + Assert.assertEquals(4, results.next()); + Assert.assertEquals(6, results.next()); + Assert.assertFalse(results.hasNext()); + + AtomicInteger count3 = new AtomicInteger(0); + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + if (count3.incrementAndGet() == 3) { + return null; + } + return batch.iterator(); + }); + Assert.assertTrue(results.hasNext()); + Assert.assertEquals(4, results.next()); + Assert.assertEquals(5, results.next()); + Assert.assertFalse(results.hasNext()); + } + + @Test + public void testMapperReturnNullThenNext() { + Iterator results; + + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + return null; + }); + Assert.assertThrows(NoSuchElementException.class, results::next); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testMapperReturnEmptyThenHasNext() { + Iterator results; + + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + return Collections.emptyIterator(); + }); + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + + AtomicInteger count1 = new AtomicInteger(0); + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + if (count1.incrementAndGet() == 1) { + return Collections.emptyIterator(); + } + return batch.iterator(); + }); + Assert.assertTrue(results.hasNext()); + Assert.assertEquals(5, results.next()); + Assert.assertEquals(6, results.next()); + Assert.assertFalse(results.hasNext()); + + AtomicInteger count2 = new AtomicInteger(0); + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + if (count2.incrementAndGet() == 2) { + return Collections.emptyIterator(); + } + return batch.iterator(); + }); + Assert.assertTrue(results.hasNext()); + Assert.assertEquals(4, results.next()); + Assert.assertEquals(6, results.next()); + Assert.assertFalse(results.hasNext()); + + AtomicInteger count3 = new AtomicInteger(0); + results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> { + if (count3.incrementAndGet() == 3) { + return Collections.emptyIterator(); + } + return batch.iterator(); + }); + Assert.assertTrue(results.hasNext()); + Assert.assertEquals(4, results.next()); + Assert.assertEquals(5, results.next()); + Assert.assertFalse(results.hasNext()); + } + + @Test + public void testClose() throws Exception { + CloseableItor vals = new CloseableItor<>(DATA1.iterator()); + + Iterator results = new BatchMapperIterator<>(1, vals, MAPPER); + + Assert.assertFalse(vals.closed()); + ((BatchMapperIterator) results).close(); + Assert.assertTrue(vals.closed()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/ExtendableIteratorTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/ExtendableIteratorTest.java new file mode 100644 index 0000000000..5e08f2d9c8 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/ExtendableIteratorTest.java @@ -0,0 +1,245 @@ +/* + * 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.unit.iterator; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import org.junit.Test; + +import org.apache.hugegraph.iterator.ExtendableIterator; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import com.google.common.collect.ImmutableList; + +@SuppressWarnings("resource") +public class ExtendableIteratorTest extends BaseUnitTest { + + private static final List DATA1 = ImmutableList.of(1); + private static final List DATA2 = ImmutableList.of(2, 3); + private static final List DATA3 = ImmutableList.of(4, 5, 6); + + @Test + public void testConcatTwoIterators() { + Iterator results = new ExtendableIterator<>(DATA1.iterator(), + DATA2.iterator()); + + List actual = new ArrayList<>(); + while (results.hasNext()) { + actual.add(results.next()); + } + + Assert.assertEquals(3, actual.size()); + Assert.assertEquals(ImmutableList.of(1, 2, 3), actual); + } + + @Test + public void testExtendIterators() { + ExtendableIterator results = new ExtendableIterator<>(); + results.extend(DATA1.iterator()) + .extend(DATA2.iterator()) + .extend(DATA3.iterator()); + + List actual = new ArrayList<>(); + while (results.hasNext()) { + actual.add(results.next()); + } + + Assert.assertEquals(6, actual.size()); + Assert.assertEquals(ImmutableList.of(1, 2, 3, 4, 5, 6), actual); + } + + @Test + public void testHasNext() { + Iterator results = new ExtendableIterator<>(DATA1.iterator()); + Assert.assertTrue(results.hasNext()); + Assert.assertTrue(results.hasNext()); + } + + @Test + public void testExtendAfterHasNext() { + ExtendableIterator results = new ExtendableIterator<>( + DATA1.iterator()); + Assert.assertTrue(results.hasNext()); + Assert.assertThrows(IllegalStateException.class, () -> { + results.extend(DATA2.iterator()); + }); + } + + @Test + public void testNext() { + Iterator results = new ExtendableIterator<>(DATA1.iterator()); + Assert.assertEquals(1, (int) results.next()); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNextWithMultiTimes() { + Iterator results = new ExtendableIterator<>(DATA1.iterator(), + DATA2.iterator()); + Assert.assertEquals(1, (int) results.next()); + Assert.assertEquals(2, (int) results.next()); + Assert.assertEquals(3, (int) results.next()); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testHasNextAndNext() { + Iterator results = new ExtendableIterator<>(DATA1.iterator()); + Assert.assertTrue(results.hasNext()); + Assert.assertTrue(results.hasNext()); + Assert.assertEquals(1, (int) results.next()); + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testRemove() { + List list1 = new ArrayList<>(DATA1); + List list3 = new ArrayList<>(DATA3); + Iterator results = new ExtendableIterator<>( + list1.iterator(), list3.iterator()); + + Assert.assertEquals(ImmutableList.of(1), list1); + Assert.assertEquals(ImmutableList.of(4, 5, 6), list3); + + results.next(); + results.remove(); + + results.next(); + results.next(); + results.remove(); + + Assert.assertEquals(0, list1.size()); + Assert.assertEquals(ImmutableList.of(4, 6), list3); + } + + @Test + public void testRemoveWithoutResult() { + Iterator results = new ExtendableIterator<>(); + Assert.assertThrows(NoSuchElementException.class, results::remove); + + List list = new ArrayList<>(); + Iterator results2 = new ExtendableIterator<>(list.iterator()); + Assert.assertThrows(NoSuchElementException.class, results2::remove); + } + + @Test + public void testClose() throws Exception { + CloseableItor c1 = new CloseableItor<>(DATA1.iterator()); + CloseableItor c2 = new CloseableItor<>(DATA2.iterator()); + CloseableItor c3 = new CloseableItor<>(DATA3.iterator()); + + ExtendableIterator results = new ExtendableIterator<>(); + results.extend(c1).extend(c2).extend(c3); + + Assert.assertFalse(c1.closed()); + Assert.assertFalse(c2.closed()); + Assert.assertFalse(c3.closed()); + + results.close(); + + Assert.assertTrue(c1.closed()); + Assert.assertTrue(c2.closed()); + Assert.assertTrue(c3.closed()); + } + + @Test + public void testCloseAfterNext1() throws Exception { + CloseableItor c1 = new CloseableItor<>(DATA1.iterator()); + CloseableItor c2 = new CloseableItor<>(DATA2.iterator()); + CloseableItor c3 = new CloseableItor<>(DATA3.iterator()); + + ExtendableIterator results = new ExtendableIterator<>(); + results.extend(c1).extend(c2).extend(c3); + + results.next(); + results.hasNext(); + + Assert.assertTrue(c1.closed()); // close after iterated + Assert.assertFalse(c2.closed()); + Assert.assertFalse(c3.closed()); + + results.close(); + + Assert.assertTrue(c1.closed()); + Assert.assertTrue(c2.closed()); + Assert.assertTrue(c3.closed()); + } + + @Test + public void testCloseAfterNext3() throws Exception { + CloseableItor c1 = new CloseableItor<>(DATA1.iterator()); + CloseableItor c2 = new CloseableItor<>(DATA2.iterator()); + CloseableItor c3 = new CloseableItor<>(DATA3.iterator()); + + ExtendableIterator results = new ExtendableIterator<>(); + results.extend(c1).extend(c2).extend(c3); + + Assert.assertFalse(c1.closed()); + Assert.assertFalse(c2.closed()); + Assert.assertFalse(c3.closed()); + + while (results.hasNext()) { + results.next(); + } + + Assert.assertTrue(c1.closed()); + Assert.assertTrue(c2.closed()); + Assert.assertFalse(c3.closed()); + + results.close(); + + Assert.assertTrue(c1.closed()); + Assert.assertTrue(c2.closed()); + Assert.assertTrue(c3.closed()); + } + + protected static class CloseableItor implements Iterator, + AutoCloseable { + + private final Iterator iter; + private boolean closed = false; + + public CloseableItor(Iterator iter) { + this.iter = iter; + } + + @Override + public boolean hasNext() { + return this.iter.hasNext(); + } + + @Override + public V next() { + return this.iter.next(); + } + + @Override + public void close() throws Exception { + this.closed = true; + } + + public boolean closed() { + return this.closed; + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/FilterIteratorTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/FilterIteratorTest.java new file mode 100644 index 0000000000..6761ef60be --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/FilterIteratorTest.java @@ -0,0 +1,179 @@ +/* + * 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.unit.iterator; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; + +import org.junit.Test; + +import org.apache.hugegraph.iterator.FilterIterator; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.unit.iterator.ExtendableIteratorTest.CloseableItor; +import com.google.common.collect.ImmutableList; + +@SuppressWarnings("resource") +public class FilterIteratorTest extends BaseUnitTest { + + private static final List DATA = ImmutableList.of(1, 2, 3, 4); + + @Test + public void testFilter() { + AtomicInteger callbackCount = new AtomicInteger(0); + + Iterator values = DATA.iterator(); + + Function filter = value -> { + callbackCount.incrementAndGet(); + return (value % 2 == 0); + }; + + Iterator results = new FilterIterator<>(values, filter); + + List actual = new ArrayList<>(); + while (results.hasNext()) { + actual.add(results.next()); + } + + Assert.assertEquals(4, callbackCount.get()); + Assert.assertEquals(ImmutableList.of(2, 4), actual); + } + + @Test + public void testHasNext() { + Iterator vals = DATA.iterator(); + + Iterator results = new FilterIterator<>(vals, val -> true); + Assert.assertTrue(results.hasNext()); + } + + @Test + public void testHasNextWithMultiTimesWithoutAnyResult() { + Iterator vals = DATA.iterator(); + + Iterator results = new FilterIterator<>(vals, val -> false); + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + } + + @Test + public void testHasNextAndNextWithMultiTimes() { + Iterator vals = DATA.iterator(); + + Iterator results = new FilterIterator<>(vals, val -> true); + + for (int i = 0; i < 5; i++) { + Assert.assertTrue(results.hasNext()); + } + + for (int i = 0; i < 4; i++) { + results.next(); + } + + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + + Assert.assertThrows(NoSuchElementException.class, results::next); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNext() { + Iterator vals = DATA.iterator(); + + Iterator results = new FilterIterator<>(vals, val -> true); + // Call next() without testNext() + results.next(); + } + + @Test + public void testNextWithMultiTimes() { + Iterator vals = DATA.iterator(); + + Iterator results = new FilterIterator<>(vals, val -> true); + for (int i = 0; i < 4; i++) { + results.next(); + } + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNextWithMultiTimesWithoutAnyResult() { + Iterator vals = DATA.iterator(); + + Iterator results = new FilterIterator<>(vals, val -> false); + Assert.assertThrows(NoSuchElementException.class, results::next); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNextWithOriginIteratorReturnNullElem() { + List list = new ArrayList<>(); + list.add(1); + list.add(null); + list.add(3); + Iterator vals = list.iterator(); + + AtomicInteger callbackCount = new AtomicInteger(0); + + Iterator results = new FilterIterator<>(vals, val -> { + callbackCount.incrementAndGet(); + return true; + }); + + Assert.assertTrue(results.hasNext()); + for (int i = 0; i < 2; i++) { + results.next(); + } + Assert.assertFalse(results.hasNext()); + Assert.assertEquals(2, callbackCount.get()); + } + + @Test + public void testRemove() { + List list = new ArrayList<>(DATA); + + Iterator results = new FilterIterator<>(list.iterator(), + val -> true); + + Assert.assertEquals(ImmutableList.of(1, 2, 3, 4), list); + + results.next(); + results.next(); + results.remove(); + + Assert.assertEquals(ImmutableList.of(1, 3, 4), list); + } + + @Test + public void testClose() throws Exception { + CloseableItor vals = new CloseableItor<>(DATA.iterator()); + + FilterIterator results = new FilterIterator<>(vals, + val -> true); + + Assert.assertFalse(vals.closed()); + results.close(); + Assert.assertTrue(vals.closed()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/FlatMapperFilterIteratorTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/FlatMapperFilterIteratorTest.java new file mode 100644 index 0000000000..6a3b658332 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/FlatMapperFilterIteratorTest.java @@ -0,0 +1,171 @@ +/* + * 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.unit.iterator; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; + +import org.junit.Test; + +import org.apache.hugegraph.iterator.FlatMapperFilterIterator; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.unit.iterator.ExtendableIteratorTest.CloseableItor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +@SuppressWarnings("resource") +public class FlatMapperFilterIteratorTest extends BaseUnitTest { + + private static final Map> DATA = ImmutableMap.of( + "first", ImmutableList.of(11), + "second", ImmutableList.of(21, 22), + "third", ImmutableList.of(31, 32, 33), + "forth", ImmutableList.of(41, 42, 43, 44) + ); + + @Test + public void testMapperFilter() { + + AtomicInteger keysCount = new AtomicInteger(0); + AtomicInteger valuesCount = new AtomicInteger(0); + + Iterator keys = DATA.keySet().iterator(); + + Function> mapper = key -> { + keysCount.incrementAndGet(); + + return DATA.get(key).iterator(); + }; + + Function filter = value -> { + valuesCount.incrementAndGet(); + + double f = value / 11F; + return (f == (int) f); + }; + + Iterator results = new FlatMapperFilterIterator<>(keys, + mapper, + filter); + + List actual = new ArrayList<>(); + while (results.hasNext()) { + actual.add(results.next()); + } + + Assert.assertEquals(4, keysCount.get()); + Assert.assertEquals(10, valuesCount.get()); + Assert.assertEquals(ImmutableList.of(11, 22, 33, 44), actual); + } + + @Test + public void testHasNext() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new FlatMapperFilterIterator<>(keys, + key -> DATA.get(key).iterator(), + val -> true); + Assert.assertTrue(results.hasNext()); + + Iterator results2 = new FlatMapperFilterIterator<>(keys, + key -> DATA.get(key).iterator(), + val -> false); + Assert.assertFalse(results2.hasNext()); + Assert.assertThrows(NoSuchElementException.class, results2::next); + } + + @Test + public void testHasNextWithMultiTimes() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new FlatMapperFilterIterator<>(keys, + key -> DATA.get(key).iterator(), + val -> true); + for (int i = 0; i < 12; i++) { + Assert.assertTrue(results.hasNext()); + } + for (int i = 0; i < 10; i++) { + results.next(); + } + Assert.assertFalse(results.hasNext()); + Assert.assertThrows(NoSuchElementException.class, results::next); + Assert.assertThrows(NoSuchElementException.class, results::next); + + Iterator results2 = new FlatMapperFilterIterator<>(keys, + key -> DATA.get(key).iterator(), + val -> false); + Assert.assertFalse(results2.hasNext()); + Assert.assertFalse(results2.hasNext()); + } + + @Test + public void testNext() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new FlatMapperFilterIterator<>(keys, + key -> DATA.get(key).iterator(), + val -> true); + // Call next() without hasNext() + results.next(); + + Iterator results2 = new FlatMapperFilterIterator<>(keys, + key -> DATA.get(key).iterator(), + val -> false); + Assert.assertThrows(NoSuchElementException.class, results2::next); + } + + @Test + public void testNextWithMultiTimes() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new FlatMapperFilterIterator<>(keys, + key -> DATA.get(key).iterator(), + val -> true); + for (int i = 0; i < 10; i++) { + results.next(); + } + Assert.assertThrows(NoSuchElementException.class, results::next); + + Iterator results2 = new FlatMapperFilterIterator<>(keys, + key -> DATA.get(key).iterator(), + val -> false); + Assert.assertThrows(NoSuchElementException.class, results2::next); + Assert.assertThrows(NoSuchElementException.class, results2::next); + } + + @Test + public void testClose() throws Exception { + CloseableItor vals = new CloseableItor<>( + DATA.keySet().iterator()); + + FlatMapperFilterIterator results; + results = new FlatMapperFilterIterator<>(vals, + k -> DATA.get(k).iterator(), + val -> true); + + Assert.assertFalse(vals.closed()); + results.close(); + Assert.assertTrue(vals.closed()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/FlatMapperIteratorTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/FlatMapperIteratorTest.java new file mode 100644 index 0000000000..641b6fc379 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/FlatMapperIteratorTest.java @@ -0,0 +1,169 @@ +/* + * 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.unit.iterator; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; + +import org.junit.Test; + +import org.apache.hugegraph.iterator.FlatMapperIterator; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.unit.iterator.ExtendableIteratorTest.CloseableItor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +@SuppressWarnings("resource") +public class FlatMapperIteratorTest extends BaseUnitTest { + + private static final Map> DATA = ImmutableMap.of( + "first", ImmutableList.of(11), + "second", ImmutableList.of(21, 22), + "third", ImmutableList.of(31, 32, 33), + "forth", ImmutableList.of(41, 42, 43, 44) + ); + + private static final Function> MAPPER = key -> { + List value = DATA.get(key); + if (value == null) { + return ImmutableList.of().iterator(); + } + return value.iterator(); + }; + + @Test + public void testFlatMapper() { + + AtomicInteger keysCount = new AtomicInteger(0); + + Iterator keys = DATA.keySet().iterator(); + + Function> mapper = key -> { + keysCount.incrementAndGet(); + + return DATA.get(key).iterator(); + }; + + Iterator results = new FlatMapperIterator<>(keys, mapper); + + List actual = new ArrayList<>(); + while (results.hasNext()) { + actual.add(results.next()); + } + + List expected = ImmutableList.of(11, + 21, 22, + 31, 32, 33, + 41, 42, 43, 44); + Assert.assertEquals(4, keysCount.get()); + Assert.assertEquals(expected, actual); + } + + @Test + public void testHasNext() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new FlatMapperIterator<>(keys, MAPPER); + Assert.assertTrue(results.hasNext()); + } + + @Test + public void testHasNextAndNextWithMultiTimes() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new FlatMapperIterator<>(keys, MAPPER); + + for (int i = 0; i < 12; i++) { + Assert.assertTrue(results.hasNext()); + } + + for (int i = 0; i < 10; i++) { + results.next(); + } + + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + + Assert.assertThrows(NoSuchElementException.class, results::next); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNext() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new FlatMapperIterator<>(keys, MAPPER); + // Call next() without hasNext() + results.next(); + } + + @Test + public void testNextWithMultiTimes() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new FlatMapperIterator<>(keys, MAPPER); + for (int i = 0; i < 10; i++) { + results.next(); + } + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testMapperReturnNullThenHasNext() { + Iterator keys = ImmutableList.of("fifth").iterator(); + + Iterator results = new FlatMapperIterator<>(keys, key -> { + Assert.assertNull(DATA.get(key)); + return null; + }); + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + } + + @Test + public void testMapperReturnNullThenNext() { + Iterator keys = ImmutableList.of("fifth").iterator(); + + Iterator results = new FlatMapperIterator<>(keys, key -> { + Assert.assertNull(DATA.get(key)); + return null; + }); + Assert.assertThrows(NoSuchElementException.class, results::next); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testClose() throws Exception { + CloseableItor vals = new CloseableItor<>( + DATA.keySet().iterator()); + + FlatMapperIterator results; + results = new FlatMapperIterator<>(vals, + key -> DATA.get(key).iterator()); + + Assert.assertFalse(vals.closed()); + results.close(); + Assert.assertTrue(vals.closed()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/LimitIteratorTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/LimitIteratorTest.java new file mode 100644 index 0000000000..f087e7df3e --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/LimitIteratorTest.java @@ -0,0 +1,181 @@ +/* + * 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.unit.iterator; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; + +import org.junit.Test; + +import org.apache.hugegraph.iterator.LimitIterator; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.unit.iterator.ExtendableIteratorTest.CloseableItor; +import com.google.common.collect.ImmutableList; + +@SuppressWarnings("resource") +public class LimitIteratorTest extends BaseUnitTest { + + private static final List DATA = ImmutableList.of(1, 2, 3, 4); + + @Test + public void testLimit() { + AtomicInteger callbackCount = new AtomicInteger(0); + + Iterator values = DATA.iterator(); + + int limit = 2; + Function filter = value -> { + return callbackCount.incrementAndGet() > limit; + }; + + Iterator results = new LimitIterator<>(values, filter); + + List actual = new ArrayList<>(); + while (results.hasNext()) { + actual.add(results.next()); + } + + Assert.assertEquals(3, callbackCount.get()); + Assert.assertEquals(ImmutableList.of(1, 2), actual); + } + + @Test + public void testHasNext() { + Iterator vals = DATA.iterator(); + + Iterator results = new LimitIterator<>(vals, val -> false); + Assert.assertTrue(results.hasNext()); + } + + @Test + public void testHasNextWithMultiTimesWithoutAnyResult() { + Iterator vals = DATA.iterator(); + + Iterator results = new LimitIterator<>(vals, val -> true); + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + } + + @Test + public void testHasNextAndNextWithMultiTimes() { + Iterator vals = DATA.iterator(); + + Iterator results = new LimitIterator<>(vals, val -> false); + + for (int i = 0; i < 5; i++) { + Assert.assertTrue(results.hasNext()); + } + + for (int i = 0; i < 4; i++) { + results.next(); + } + + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + + Assert.assertThrows(NoSuchElementException.class, results::next); + Assert.assertThrows(NoSuchElementException.class, results::next); + + Iterator results2 = new LimitIterator<>(vals, val -> false); + Assert.assertFalse(results2.hasNext()); + } + + @Test + public void testNext() { + Iterator vals = DATA.iterator(); + + Iterator results = new LimitIterator<>(vals, val -> false); + // Call next() without testNext() + results.next(); + } + + @Test + public void testNextWithMultiTimes() { + Iterator vals = DATA.iterator(); + + Iterator results = new LimitIterator<>(vals, val -> false); + for (int i = 0; i < 4; i++) { + results.next(); + } + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNextWithMultiTimesWithoutAnyResult() { + Iterator vals = DATA.iterator(); + + Iterator results = new LimitIterator<>(vals, val -> true); + Assert.assertThrows(NoSuchElementException.class, results::next); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNextWithOriginIteratorReturnNullElem() { + List list = new ArrayList<>(); + list.add(1); + list.add(null); + list.add(3); + Iterator vals = list.iterator(); + + AtomicInteger callbackCount = new AtomicInteger(0); + + Iterator results = new LimitIterator<>(vals, val -> { + callbackCount.incrementAndGet(); + return false; + }); + Assert.assertTrue(results.hasNext()); + for (int i = 0; i < 2; i++) { + results.next(); + } + Assert.assertFalse(results.hasNext()); + Assert.assertEquals(2, callbackCount.get()); + } + + @Test + public void testRemove() { + List list = new ArrayList<>(DATA); + + Iterator results = new LimitIterator<>(list.iterator(), + val -> false); + + Assert.assertEquals(ImmutableList.of(1, 2, 3, 4), list); + + results.next(); + results.next(); + results.remove(); + + Assert.assertEquals(ImmutableList.of(1, 3, 4), list); + } + + @Test + public void testClose() throws Exception { + CloseableItor vals = new CloseableItor<>(DATA.iterator()); + + LimitIterator results = new LimitIterator<>(vals, + val -> true); + + Assert.assertFalse(vals.closed()); + results.close(); + Assert.assertTrue(vals.closed()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/ListIteratorTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/ListIteratorTest.java new file mode 100644 index 0000000000..659ab482ed --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/ListIteratorTest.java @@ -0,0 +1,232 @@ +/* + * 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.unit.iterator; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import org.junit.Test; + +import org.apache.hugegraph.iterator.ListIterator; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.unit.iterator.ExtendableIteratorTest.CloseableItor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterators; + +@SuppressWarnings("resource") +public class ListIteratorTest extends BaseUnitTest { + + private static final Iterator EMPTY = Collections.emptyIterator(); + + private static final List DATA1 = ImmutableList.of(1); + private static final List DATA2 = ImmutableList.of(2, 3); + private static final List DATA3 = ImmutableList.of(4, 5, 6); + + @Test + public void testCapacity() { + Iterator results; + + results = new ListIterator<>(0, EMPTY); + Assert.assertFalse(results.hasNext()); + Assert.assertEquals(0, Iterators.size(results)); + + results = new ListIterator<>(2, DATA1.iterator()); + Assert.assertTrue(results.hasNext()); + Assert.assertEquals(1, Iterators.size(results)); + + results = new ListIterator<>(2, DATA2.iterator()); + Assert.assertTrue(results.hasNext()); + Assert.assertEquals(2, Iterators.size(results)); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + new ListIterator<>(0, DATA1.iterator()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + new ListIterator<>(2, DATA3.iterator()); + }); + } + + @Test + public void testList() { + ListIterator results; + + results = new ListIterator<>(-1, EMPTY); + Assert.assertEquals(ImmutableList.of(), results.list()); + + results = new ListIterator<>(-1, DATA1.iterator()); + Assert.assertEquals(ImmutableList.of(1), results.list()); + + results = new ListIterator<>(-1, DATA2.iterator()); + Assert.assertEquals(ImmutableList.of(2, 3), results.list()); + + results = new ListIterator<>(-1, DATA3.iterator()); + Assert.assertEquals(ImmutableList.of(4, 5, 6), results.list()); + } + + @Test + public void testHasNext() { + Iterator origin = DATA1.iterator(); + Assert.assertTrue(origin.hasNext()); + + Iterator results = new ListIterator<>(-1, origin); + Assert.assertTrue(results.hasNext()); + Assert.assertTrue(results.hasNext()); + Assert.assertFalse(origin.hasNext()); + } + + @Test + public void testNext() { + Iterator results = new ListIterator<>(-1, DATA1.iterator()); + Assert.assertEquals(1, (int) results.next()); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNextAfterList() { + Iterator results = new ListIterator<>(-1, DATA1.iterator()); + Assert.assertEquals(ImmutableList.of(1), + ((ListIterator) results).list()); + Assert.assertEquals(1, (int) results.next()); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNextWithMultiTimes() { + Iterator results = new ListIterator<>(-1, DATA2.iterator()); + Assert.assertEquals(2, (int) results.next()); + Assert.assertEquals(3, (int) results.next()); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testHasNextAndNext() { + Iterator results = new ListIterator<>(-1, DATA1.iterator()); + Assert.assertTrue(results.hasNext()); + Assert.assertTrue(results.hasNext()); + Assert.assertEquals(1, (int) results.next()); + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testRemove() { + List list = new ArrayList<>(DATA3); + ListIterator results = new ListIterator<>(-1, list.iterator()); + + Assert.assertEquals(ImmutableList.of(4, 5, 6), list); + Assert.assertEquals(ImmutableList.of(4, 5, 6), results.list()); + + Assert.assertThrows(UnsupportedOperationException.class, results::remove); + results.next(); + Assert.assertThrows(UnsupportedOperationException.class, results::remove); + + Assert.assertEquals(ImmutableList.of(4, 5, 6), list); + Assert.assertEquals(ImmutableList.of(4, 5, 6), results.list()); + } + + @Test + public void testRemoveWithoutResult() { + Iterator results = new ListIterator<>(-1, EMPTY); + Assert.assertThrows(UnsupportedOperationException.class, results::remove); + + List list0 = new ArrayList<>(); + Iterator results2 = new ListIterator<>(-1, list0.iterator()); + Assert.assertThrows(UnsupportedOperationException.class, results2::remove); + } + + @Test + public void testClose() throws Exception { + CloseableItor c1 = new CloseableItor<>(DATA1.iterator()); + + ListIterator results = new ListIterator<>(-1, c1); + + Assert.assertFalse(c1.closed()); + + results.close(); + + Assert.assertTrue(c1.closed()); + } + + @Test + public void testListWithConstructFromList() { + ListIterator results; + + results = new ListIterator<>(ImmutableList.of()); + Assert.assertEquals(ImmutableList.of(), results.list()); + + results = new ListIterator<>(DATA1); + Assert.assertEquals(ImmutableList.of(1), results.list()); + + results = new ListIterator<>(DATA2); + Assert.assertEquals(ImmutableList.of(2, 3), results.list()); + + results = new ListIterator<>(DATA3); + Assert.assertEquals(ImmutableList.of(4, 5, 6), results.list()); + } + + @Test + public void testHasNextAndNextWithConstructFromList() { + ListIterator results0 = new ListIterator<>(ImmutableList.of()); + Assert.assertFalse(results0.hasNext()); + Assert.assertThrows(NoSuchElementException.class, results0::next); + + ListIterator results1 = new ListIterator<>(DATA1); + Assert.assertTrue(results1.hasNext()); + Assert.assertEquals(1, results1.next()); + Assert.assertFalse(results1.hasNext()); + Assert.assertThrows(NoSuchElementException.class, results1::next); + + ListIterator results3 = new ListIterator<>(DATA3); + Assert.assertTrue(results3.hasNext()); + Assert.assertEquals(4, results3.next()); + Assert.assertTrue(results3.hasNext()); + Assert.assertEquals(5, results3.next()); + Assert.assertTrue(results3.hasNext()); + Assert.assertEquals(6, results3.next()); + Assert.assertFalse(results3.hasNext()); + Assert.assertThrows(NoSuchElementException.class, results3::next); + } + + @Test + public void testNextWithConstructFromList() { + ListIterator results0 = new ListIterator<>(ImmutableList.of()); + Assert.assertThrows(NoSuchElementException.class, results0::next); + + ListIterator results3 = new ListIterator<>(DATA3); + Assert.assertEquals(4, results3.next()); + Assert.assertEquals(5, results3.next()); + Assert.assertEquals(6, results3.next()); + Assert.assertThrows(NoSuchElementException.class, results3::next); + } + + @Test + public void testNextAfterListWithConstructFromList() { + ListIterator results3 = new ListIterator<>(DATA3); + Assert.assertEquals(ImmutableList.of(4, 5, 6), results3.list()); + Assert.assertEquals(4, results3.next()); + Assert.assertEquals(5, results3.next()); + Assert.assertEquals(6, results3.next()); + Assert.assertThrows(NoSuchElementException.class, results3::next); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/MapperIteratorTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/MapperIteratorTest.java new file mode 100644 index 0000000000..4f36e857ce --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/iterator/MapperIteratorTest.java @@ -0,0 +1,154 @@ +/* + * 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.unit.iterator; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; + +import org.junit.Test; + +import org.apache.hugegraph.iterator.MapperIterator; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.unit.iterator.ExtendableIteratorTest.CloseableItor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +@SuppressWarnings("resource") +public class MapperIteratorTest extends BaseUnitTest { + + private static final Map DATA = ImmutableMap.of( + "first", 1, + "second", 2, + "third", 3, + "forth", 4 + ); + + private static final Function MAPPER = DATA::get; + + @Test + public void testMapper() { + + AtomicInteger keysCount = new AtomicInteger(0); + + Iterator keys = DATA.keySet().iterator(); + + Function mapper = key -> { + keysCount.incrementAndGet(); + + return DATA.get(key); + }; + + Iterator results = new MapperIterator<>(keys, mapper); + + List actual = new ArrayList<>(); + while (results.hasNext()) { + actual.add(results.next()); + } + + List expected = ImmutableList.of(1, 2, 3, 4); + Assert.assertEquals(4, keysCount.get()); + Assert.assertEquals(expected, actual); + } + + @Test + public void testHasNext() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new MapperIterator<>(keys, MAPPER); + Assert.assertTrue(results.hasNext()); + } + + @Test + public void testHasNextAndNextWithMultiTimes() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new MapperIterator<>(keys, MAPPER); + + for (int i = 0; i < 5; i++) { + Assert.assertTrue(results.hasNext()); + } + + for (int i = 0; i < 4; i++) { + results.next(); + } + + Assert.assertFalse(results.hasNext()); + Assert.assertFalse(results.hasNext()); + + Assert.assertThrows(NoSuchElementException.class, results::next); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testNext() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new MapperIterator<>(keys, MAPPER); + // Call next() without hasNext() + results.next(); + } + + @Test + public void testNextWithMultiTimes() { + Iterator keys = DATA.keySet().iterator(); + + Iterator results = new MapperIterator<>(keys, MAPPER); + for (int i = 0; i < 4; i++) { + results.next(); + } + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testMapperReturnNullThenHasNext() { + Iterator keys = ImmutableList.of("fifth").iterator(); + + Iterator results = new MapperIterator<>(keys, key -> { + return null; + }); + Assert.assertFalse(results.hasNext()); + } + + @Test + public void testMapperReturnNullThenNext() { + Iterator keys = ImmutableList.of("fifth").iterator(); + + Iterator results = new MapperIterator<>(keys, key -> { + return null; + }); + Assert.assertThrows(NoSuchElementException.class, results::next); + } + + @Test + public void testClose() throws Exception { + CloseableItor keys = new CloseableItor<>( + ImmutableList.of("fifth").iterator()); + + MapperIterator results = new MapperIterator<>(keys, k -> null); + + Assert.assertFalse(keys.closed()); + results.close(); + Assert.assertTrue(keys.closed()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseCreateParamTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseCreateParamTest.java new file mode 100644 index 0000000000..67e6a54808 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseCreateParamTest.java @@ -0,0 +1,103 @@ +/* + * 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.unit.license; + +import java.io.IOException; + +import org.apache.hugegraph.date.SafeDateFormat; +import org.apache.hugegraph.license.LicenseCreateParam; +import org.apache.hugegraph.testutil.Assert; +import org.junit.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class LicenseCreateParamTest { + + @Test + public void testDeserializeLicenseCreateParam() throws IOException { + String json = "{" + + "\"subject\":\"hugegraph-evaluation\"," + + "\"private_alias\":\"privatekey\"," + + "\"key_ticket\":\"a123456\"," + + "\"store_ticket\":\"a123456\"," + + "\"privatekey_path\":\"./privateKeys.store\"," + + "\"license_path\":\"./hugegraph-evaluation.license\"," + + "\"issued_time\":\"2019-08-10 00:00:00\"," + + "\"not_before\":\"2019-08-10 00:00:00\"," + + "\"not_after\":\"2020-08-10 00:00:00\"," + + "\"consumer_type\":\"user\"," + + "\"consumer_amount\":1," + + "\"description\":\"hugegraph license\"," + + "\"extra_params\":[" + + "{" + + "\"id\":\"server-1\"," + + "\"version\":\"0.9.2\"," + + "\"graphs\":3," + + "\"ip\":\"127.0.0.1\"," + + "\"mac\":\"00-01-6C-06-A6-29\"," + + "\"cpus\":32," + + "\"ram\":65536," + + "\"threads\":96," + + "\"memory\":32768," + + "\"nodes\":3," + + "\"data_size\":1024," + + "\"vertices\":1000," + + "\"edges\":2000" + + "}," + + "{" + + "\"id\":\"server-2\"," + + "\"version\":\"0.10.2\"," + + "\"graphs\":3," + + "\"ip\":\"127.0.0.1\"," + + "\"mac\":\"00-02-6C-06-A6-29\"," + + "\"cpus\":64," + + "\"ram\":65536," + + "\"threads\":96," + + "\"memory\":65536," + + "\"nodes\":30," + + "\"data_size\":10240," + + "\"vertices\":10000," + + "\"edges\":20000" + + "}" + + "]" + + "}"; + ObjectMapper mapper = new ObjectMapper(); + LicenseCreateParam param = mapper.readValue(json, + LicenseCreateParam.class); + Assert.assertEquals("hugegraph-evaluation", param.subject()); + Assert.assertEquals("privatekey", param.privateAlias()); + Assert.assertEquals("a123456", param.keyPassword()); + Assert.assertEquals("a123456", param.storePassword()); + Assert.assertEquals("./privateKeys.store", param.privateKeyPath()); + Assert.assertEquals("./hugegraph-evaluation.license", + param.licensePath()); + + SafeDateFormat df = new SafeDateFormat("yyyy-MM-dd HH:mm:ss"); + df.setTimeZone("GMT+8"); + Assert.assertEquals(df.parse("2019-08-10 00:00:00"), + param.issuedTime()); + Assert.assertEquals(df.parse("2019-08-10 00:00:00"), + param.notBefore()); + Assert.assertEquals(df.parse("2020-08-10 00:00:00"), + param.notAfter()); + Assert.assertEquals("user", param.consumerType()); + Assert.assertEquals(1, param.consumerAmount()); + Assert.assertEquals("hugegraph license", param.description()); + Assert.assertEquals(2, param.extraParams().size()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseExtraParamTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseExtraParamTest.java new file mode 100644 index 0000000000..b24470d2a4 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseExtraParamTest.java @@ -0,0 +1,63 @@ +/* + * 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.unit.license; + +import java.io.IOException; + +import org.apache.hugegraph.license.LicenseExtraParam; +import org.junit.Test; + +import org.apache.hugegraph.testutil.Assert; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class LicenseExtraParamTest { + + @Test + public void testDeserializeExtraParam() throws IOException { + String json = "{" + + "\"id\":\"server-1\"," + + "\"version\":\"0.10.2\"," + + "\"graphs\":3," + + "\"ip\":\"127.0.0.1\"," + + "\"mac\":\"00-01-6C-06-A6-29\"," + + "\"cpus\":32," + + "\"ram\":65536," + + "\"threads\":96," + + "\"memory\":32768," + + "\"nodes\":3," + + "\"data_size\":1024," + + "\"vertices\":1000," + + "\"edges\":2000" + + "}"; + ObjectMapper mapper = new ObjectMapper(); + LicenseExtraParam param = mapper.readValue(json, LicenseExtraParam.class); + Assert.assertEquals("server-1", param.id()); + Assert.assertEquals("0.10.2", param.version()); + Assert.assertEquals(3, param.graphs()); + Assert.assertEquals("127.0.0.1", param.ip()); + Assert.assertEquals("00-01-6C-06-A6-29", param.mac()); + Assert.assertEquals(32, param.cpus()); + Assert.assertEquals(65536, param.ram()); + Assert.assertEquals(96, param.threads()); + Assert.assertEquals(32768, param.memory()); + Assert.assertEquals(3, param.nodes()); + Assert.assertEquals(1024, param.dataSize()); + Assert.assertEquals(1000, param.vertices()); + Assert.assertEquals(2000, param.edges()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseInstallParamTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseInstallParamTest.java new file mode 100644 index 0000000000..ed38d93f6f --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseInstallParamTest.java @@ -0,0 +1,49 @@ +/* + * 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.unit.license; + +import java.io.IOException; + +import org.junit.Test; + +import org.apache.hugegraph.license.LicenseInstallParam; +import org.apache.hugegraph.testutil.Assert; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class LicenseInstallParamTest { + + @Test + public void testDeserializeLicenseVerifyParam() throws IOException { + String json = "{" + + "\"subject\":\"hugegraph-evaluation\"," + + "\"public_alias\":\"publiccert\"," + + "\"store_ticket\":\"a123456\"," + + "\"publickey_path\":\"./publicCerts.store\"," + + "\"license_path\":\"./hugegraph-evaluation.license\"" + + "}"; + ObjectMapper mapper = new ObjectMapper(); + LicenseInstallParam param = mapper.readValue(json, + LicenseInstallParam.class); + Assert.assertEquals("hugegraph-evaluation", param.subject()); + Assert.assertEquals("publiccert", param.publicAlias()); + Assert.assertEquals("a123456", param.storePassword()); + Assert.assertEquals("./publicCerts.store", param.publicKeyPath()); + Assert.assertEquals("./hugegraph-evaluation.license", + param.licensePath()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseParamsTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseParamsTest.java new file mode 100644 index 0000000000..9a2968d6f8 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/LicenseParamsTest.java @@ -0,0 +1,86 @@ +/* + * 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.unit.license; + +import java.io.IOException; + +import org.apache.hugegraph.license.LicenseExtraParam; +import org.apache.hugegraph.license.LicenseParams; +import org.junit.Test; + +import org.apache.hugegraph.testutil.Assert; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class LicenseParamsTest { + + @Test + public void testLicenseParams() throws IOException { + String json = "{" + + "\"subject\":\"hugegraph-evaluation\"," + + "\"issued_time\":\"2019-08-10 00:00:00\"," + + "\"not_before\":\"2019-08-10 00:00:00\"," + + "\"not_after\":\"2020-08-10 00:00:00\"," + + "\"consumer_type\":\"user\"," + + "\"consumer_amount\":1," + + "\"description\":\"hugegraph license\"," + + "\"extra_params\":[" + + "{" + + "\"id\":\"server-1\"," + + "\"version\":\"0.9.2\"," + + "\"graphs\":3," + + "\"ip\":\"127.0.0.1\"," + + "\"mac\":\"00-01-6C-06-A6-29\"," + + "\"cpus\":32," + + "\"ram\":65536," + + "\"threads\":96," + + "\"memory\":32768," + + "\"nodes\":3," + + "\"data_size\":1024," + + "\"vertices\":1000," + + "\"edges\":2000" + + "}," + + "{" + + "\"id\":\"server-2\"," + + "\"version\":\"0.10.2\"," + + "\"graphs\":3," + + "\"ip\":\"127.0.0.1\"," + + "\"mac\":\"00-02-6C-06-A6-29\"," + + "\"cpus\":64," + + "\"ram\":65536," + + "\"threads\":96," + + "\"memory\":65536," + + "\"nodes\":30," + + "\"data_size\":10240," + + "\"vertices\":10000," + + "\"edges\":20000" + + "}" + + "]" + + "}"; + ObjectMapper mapper = new ObjectMapper(); + LicenseParams param = mapper.readValue(json, LicenseParams.class); + + LicenseExtraParam extraParam = param.matchParam("server-not-exist"); + Assert.assertNull(extraParam); + + extraParam = param.matchParam("server-1"); + Assert.assertEquals("00-01-6C-06-A6-29", extraParam.mac()); + + extraParam = param.matchParam("server-2"); + Assert.assertEquals("00-02-6C-06-A6-29", extraParam.mac()); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/MachineInfoTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/MachineInfoTest.java new file mode 100644 index 0000000000..9dc69cbdb9 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/license/MachineInfoTest.java @@ -0,0 +1,87 @@ +/* + * 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.unit.license; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.List; +import java.util.regex.Pattern; + +import org.junit.Test; + +import org.apache.hugegraph.license.MachineInfo; +import org.apache.hugegraph.testutil.Assert; + +public class MachineInfoTest { + + private static final Pattern IPV4_PATTERN = Pattern.compile( + "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}" + + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$" + ); + private static final Pattern IPV6_PATTERN = Pattern.compile( + "^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$" + ); + + private static final Pattern MAC_PATTERN = Pattern.compile( + "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$" + ); + + private static final MachineInfo machineInfo = new MachineInfo(); + + @Test + public void testGetIpAddressList() { + List ipAddressList = machineInfo.getIpAddress(); + for (String ip : ipAddressList) { + Assert.assertTrue(IPV4_PATTERN.matcher(ip).matches() || + IPV6_PATTERN.matcher(ip).matches()); + } + Assert.assertEquals(ipAddressList, machineInfo.getIpAddress()); + } + + @Test + public void testGetMacAddressList() { + List macAddressList = machineInfo.getMacAddress(); + for (String mac : macAddressList) { + Assert.assertTrue(MAC_PATTERN.matcher(mac).matches()); + } + Assert.assertEquals(macAddressList, machineInfo.getMacAddress()); + } + + @Test + public void testGetLocalAllInetAddress() { + List addressList = machineInfo.getLocalAllInetAddress(); + for (InetAddress address : addressList) { + String ip = address.getHostAddress(); + Assert.assertTrue(IPV4_PATTERN.matcher(ip).matches() || + IPV6_PATTERN.matcher(ip).matches()); + } + } + + @Test + public void testGetMacByInetAddress() throws UnknownHostException { + List addressList = machineInfo.getLocalAllInetAddress(); + for (InetAddress address : addressList) { + String mac = machineInfo.getMacByInetAddress(address); + Assert.assertTrue(MAC_PATTERN.matcher(mac).matches()); + } + InetAddress address = InetAddress.getByAddress(new byte[]{0, 0, 0, 0}); + Assert.assertThrows(RuntimeException.class, () -> { + machineInfo.getMacByInetAddress(address); + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/PerfUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/PerfUtilTest.java new file mode 100644 index 0000000000..1fcb50711a --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/PerfUtilTest.java @@ -0,0 +1,468 @@ +/* + * 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.unit.perf; + +import java.util.Map; + +import org.junit.After; +import org.junit.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.perf.testclass.TestClass; +import org.apache.hugegraph.unit.perf.testclass.TestPerfLightClass; +import org.apache.hugegraph.unit.perf.testclass2.TestClass4Package; +import org.apache.hugegraph.perf.PerfUtil; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.unit.perf.testclass.TestLightClass; +import org.apache.hugegraph.unit.perf.testclass.TestPerfClass; + +public class PerfUtilTest extends BaseUnitTest { + + private static final String prefix = + "org.apache.hugegraph.unit.perf.testclass."; + private static final PerfUtil perf = PerfUtil.instance(); + + @After + public void teardown() { + perf.clear(); + } + + @Test + public void testPerfUtil() throws Throwable { + perf.profileClass(prefix + "TestClass$Foo"); + + TestClass.Foo obj = new TestClass.Foo(); + obj.foo(); + + perf.toString(); + perf.toECharts(); + String json = perf.toJson(); + + assertContains(json, "foo.foo#times", 1); + assertContains(json, "foo.foo#name", "foo.foo"); + assertContains(json, "foo.foo#parent", ""); + assertContains(json, "foo.foo#total_cost"); + assertContains(json, "foo.foo#min_cost"); + assertContains(json, "foo.foo#max_cost"); + assertContains(json, "foo.foo#total_self_wasted"); + assertContains(json, "foo.foo#total_children_wasted", -1); + assertContains(json, "foo.foo#total_children_times", -1); + + assertContains(json, "foo.foo/foo.bar#times", 1); + assertContains(json, "foo.foo/foo.bar#name", "foo.bar"); + assertContains(json, "foo.foo/foo.bar#parent", "foo.foo"); + assertContains(json, "foo.foo/foo.bar#total_cost"); + assertContains(json, "foo.foo/foo.bar#min_cost"); + assertContains(json, "foo.foo/foo.bar#max_cost"); + assertContains(json, "foo.foo/foo.bar#total_self_wasted"); + assertContains(json, "foo.foo/foo.bar#total_children_wasted", -1); + assertContains(json, "foo.foo/foo.bar#total_children_times", -1); + + TestClass test = new TestClass(); + test.test(); + json = perf.toJson(); + assertContains(json, "foo.bar#times", 1); + assertContains(json, "foo.foo#times", 1); + assertContains(json, "foo.foo/foo.bar#times", 1); + + perf.clear(); + + obj.foo(); + obj.foo(); + + perf.toString(); + perf.toECharts(); + json = perf.toJson(); + + assertContains(json, "foo.foo#times", 2); + assertContains(json, "foo.foo/foo.bar#times", 2); + } + + @Test + public void testPerfUtil4LightStopwatch() throws Throwable { + perf.profileClass(prefix + "TestLightClass$Foo"); + + PerfUtil.useLightStopwatch(true); + + TestLightClass.Foo obj = new TestLightClass.Foo(); + obj.foo(); + + perf.toString(); + perf.toECharts(); + String json = perf.toJson(); + + assertContains(json, "foo.foo#times", 1); + assertContains(json, "foo.foo#name", "foo.foo"); + assertContains(json, "foo.foo#parent", ""); + assertContains(json, "foo.foo#total_cost"); + assertContains(json, "foo.foo#min_cost"); + assertContains(json, "foo.foo#max_cost"); + assertContains(json, "foo.foo#total_self_wasted"); + assertContains(json, "foo.foo#total_children_wasted", -1); + assertContains(json, "foo.foo#total_children_times", -1); + + assertContains(json, "foo.foo/foo.bar#times", 1); + assertContains(json, "foo.foo/foo.bar#name", "foo.bar"); + assertContains(json, "foo.foo/foo.bar#parent", "foo.foo"); + assertContains(json, "foo.foo/foo.bar#total_cost"); + assertContains(json, "foo.foo/foo.bar#min_cost"); + assertContains(json, "foo.foo/foo.bar#max_cost"); + assertContains(json, "foo.foo/foo.bar#total_self_wasted"); + assertContains(json, "foo.foo/foo.bar#total_children_wasted", -1); + assertContains(json, "foo.foo/foo.bar#total_children_times", -1); + + perf.clear(); + + obj.foo(); + obj.foo(); + + perf.toString(); + perf.toECharts(); + json = perf.toJson(); + + assertContains(json, "foo.foo#times", 2); + assertContains(json, "foo.foo/foo.bar#times", 2); + + perf.clear(); + PerfUtil.useLightStopwatch(false); + } + + @Test + public void testPerfUtil4LightStopwatcAndSwitch() throws Throwable { + perf.profileClass(prefix + "TestLightClass$Bar"); + + TestLightClass.Bar bar = new TestLightClass.Bar(); + bar.foo(); + + perf.toString(); + perf.toECharts(); + String json = perf.toJson(); + + assertContains(json, "bar.foo#times", 1); + assertContains(json, "bar.foo/bar.bar#times", 1); + + PerfUtil.useLightStopwatch(false); + bar.foo(); + json = perf.toJson(); + + assertContains(json, "bar.foo#times", 2); + assertContains(json, "bar.foo/bar.bar#times", 2); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + PerfUtil.useLightStopwatch(true); + }, e -> { + Assert.assertContains("clear() before switching light-stopwatch", + e.getMessage()); + }); + + // Test switch from normal-watch to light-watch + perf.clear(); + PerfUtil.useLightStopwatch(true); + bar.foo(); + + perf.toString(); + perf.toECharts(); + json = perf.toJson(); + + assertContains(json, "bar.foo#times", 1); + assertContains(json, "bar.foo/bar.bar#times", 1); + + bar.foo(); + json = perf.toJson(); + + assertContains(json, "bar.foo#times", 2); + assertContains(json, "bar.foo/bar.bar#times", 2); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + PerfUtil.useLightStopwatch(false); + }, e -> { + Assert.assertContains("clear() before switching light-stopwatch", + e.getMessage()); + }); + + // Test switch from light-watch to normal-watch + perf.clear(); + PerfUtil.useLightStopwatch(false); + bar.foo(); + + perf.toString(); + perf.toECharts(); + json = perf.toJson(); + + assertContains(json, "bar.foo#times", 1); + assertContains(json, "bar.foo/bar.bar#times", 1); + } + + @Test + public void testPerfUtilWithSingleThread() throws Throwable { + perf.profileClass(prefix + "TestClass$Bar"); + PerfUtil.profileSingleThread(true); + + TestClass.Bar obj = new TestClass.Bar(); + obj.foo(); + perf.toString(); + perf.toECharts(); + String json = perf.toJson(); + + assertContains(json, "bar_foo#times", 1); + assertContains(json, "bar_foo/bar_bar#times", 1); + + perf.clear(); + + obj.foo(); + obj.foo(); + + perf.toString(); + perf.toECharts(); + json = perf.toJson(); + + assertContains(json, "bar_foo#times", 2); + assertContains(json, "bar_foo/bar_bar#times", 2); + + PerfUtil.profileSingleThread(false); + + obj.foo(); + + perf.toString(); + perf.toECharts(); + json = perf.toJson(); + + assertContains(json, "bar_foo#times", 3); + assertContains(json, "bar_foo/bar_bar#times", 3); + } + + @Test + public void testPerfUtilWithProfilePackage() throws Throwable { + perf.profilePackage("org.apache.hugegraph.unit.perf.testclass2"); + + TestClass4Package.Foo obj = new TestClass4Package.Foo(); + obj.foo(); + + perf.toString(); + perf.toECharts(); + String json = perf.toJson(); + + assertContains(json, "foo#times", 1); + assertContains(json, "foo/bar#times", 1); + + TestClass4Package test = new TestClass4Package(); + test.test(); + json = perf.toJson(); + assertContains(json, "test#times", 1); + assertContains(json, "test/bar#times", 1); + assertContains(json, "foo#times", 1); + assertContains(json, "foo/bar#times", 1); + + perf.clear(); + + obj.foo(); + obj.foo(); + + perf.toString(); + perf.toECharts(); + json = perf.toJson(); + + assertContains(json, "foo#times", 2); + assertContains(json, "foo/bar#times", 2); + } + + @Test + public void testPerfUtilWithProfileParentClass() throws Throwable { + perf.profileClass(prefix + "TestClass$Base"); + perf.profileClass(prefix + "TestClass$Sub"); + + TestClass.Sub obj = new TestClass.Sub(); + obj.func(); + obj.func1(); + obj.func2(); + obj.func3(); + obj.func3(); + obj.func3(); + + perf.toString(); + perf.toECharts(); + String json = perf.toJson(); + assertContains(json, "func#times", 1); + assertContains(json, "func1#times", 1); + assertContains(json, "func3#times", 3); + } + + @Test + public void testPerfUtilWithProfileManually() throws Throwable { + perf.profileClass(prefix + "TestClass$ManuallyProfile"); + + TestClass.ManuallyProfile obj = new TestClass.ManuallyProfile(); + + obj.foo(); + + perf.toString(); + perf.toECharts(); + String json = perf.toJson(); + + assertContains(json, "manu-foo#times", 1); + assertContains(json, "manu-foo/manu-bar#times", 1); + assertContains(json, "manu-foo/manu-bar2#times", 1); + + obj.foo(); + obj.bar(); + + perf.toString(); + perf.toECharts(); + json = perf.toJson(); + + assertContains(json, "manu-foo#times", 2); + assertContains(json, "manu-foo/manu-bar#times", 2); + assertContains(json, "manu-bar#times", 1); + + obj.foo2(); + obj.bar2(); + + perf.toString(); + perf.toECharts(); + json = perf.toJson(); + + assertContains(json, "manu-foo2#times", 1); + assertContains(json, "manu-foo2/manu-bar#times#times", 1); + assertContains(json, "manu-foo2/manu-bar2#times#times", 1); + assertContains(json, "manu-foo#times", 2); + assertContains(json, "manu-foo/manu-bar#times", 2); + assertContains(json, "manu-bar#times", 1); + assertContains(json, "manu-bar2#times", 1); + } + + @Test + public void testPerfUtilPerf() throws Throwable { + perf.profileClass(prefix + "TestPerfClass"); + perf.profileClass(prefix + "TestPerfClass$Foo"); + + PerfUtil.profileSingleThread(true); + PerfUtil.useLocalTimer(true); + + int times = 10000000; + TestPerfClass test = new TestPerfClass(); + test.test(times); + test.testNew(); + + perf.toString(); + perf.toECharts(); + String json = perf.toJson(); + + assertContains(json, "testNew#times", 1); + assertContains(json, "test/testNew#times", times); + assertContains(json, "test/testNewAndCall#times", times); + assertContains(json, "test/testCall#times", times); + assertContains(json, "test/testCallFooThenSum#times", times); + + assertContains(json, "test/testNewAndCall/sum#times", times); + assertContains(json, "test/testCall/sum#times", times); + assertContains(json, "test/testCallFooThenSum/foo#times", times); + assertContains(json, "test/testCallFooThenSum/foo/sum#times", times); + + // Test call multi-times and Reset false + PerfUtil.profileSingleThread(true); + PerfUtil.profileSingleThread(true); + PerfUtil.profileSingleThread(false); + PerfUtil.profileSingleThread(false); + PerfUtil.useLocalTimer(true); + PerfUtil.useLocalTimer(true); + PerfUtil.useLocalTimer(false); + PerfUtil.useLocalTimer(false); + + test.testNew(); + json = perf.toJson(); + assertContains(json, "testNew#times", 2); + } + + @Test + public void testPerfUtilPerf4LightStopwatch() throws Throwable { + perf.profileClass(prefix + "TestPerfLightClass"); + perf.profileClass(prefix + "TestPerfLightClass$Foo"); + + PerfUtil.profileSingleThread(true); + PerfUtil.useLightStopwatch(true); + PerfUtil.useLocalTimer(true); + + int times = 10000000; + TestPerfLightClass test = new TestPerfLightClass(); + test.test(times); + test.testNew(); + + perf.toString(); + perf.toECharts(); + String json = perf.toJson(); + + assertContains(json, "testNew#times", 1); + assertContains(json, "test/testNew#times", times); + assertContains(json, "test/testNewAndCall#times", times); + assertContains(json, "test/testCall#times", times); + assertContains(json, "test/testCallFooThenSum#times", times); + + assertContains(json, "test/testNewAndCall/sum#times", times); + assertContains(json, "test/testCall/sum#times", times); + assertContains(json, "test/testCallFooThenSum/foo#times", times); + assertContains(json, "test/testCallFooThenSum/foo/sum#times", times); + + // Test reset and call multi-times + PerfUtil.profileSingleThread(true); + PerfUtil.profileSingleThread(true); + PerfUtil.profileSingleThread(false); + PerfUtil.profileSingleThread(false); + + PerfUtil.useLocalTimer(true); + PerfUtil.useLocalTimer(true); + PerfUtil.useLocalTimer(false); + PerfUtil.useLocalTimer(false); + + perf.clear(); + PerfUtil.useLightStopwatch(false); + PerfUtil.useLightStopwatch(false); + + test.testNew(); + json = perf.toJson(); + assertContains(json, "testNew#times", 1); + } + + private static void assertContains(String json, String key) + throws Exception { + Assert.assertNotNull("Not exist key " + key, actualValue(json, key)); + } + + private static void assertContains(String json, String key, Object value) + throws Exception { + String error = String.format("not contains key '%s' with value <%s> " + + "in json: %s.\n", key, value, json); + Assert.assertEquals(error, value, actualValue(json, key)); + } + + private static Object actualValue(String json, String key) + throws Exception { + ObjectMapper mapper = new ObjectMapper(); + Map map = mapper.readValue(json, Map.class); + String[] keys = key.split("#"); + Object actual = null; + for (String k : keys) { + actual = map.get(k); + if (actual instanceof Map) { + map = (Map) actual; + } + } + return actual; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/StopwatchTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/StopwatchTest.java new file mode 100644 index 0000000000..6a6c7865d9 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/StopwatchTest.java @@ -0,0 +1,102 @@ +/* + * 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.unit.perf; + +import org.junit.Test; + +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.perf.LightStopwatch; +import org.apache.hugegraph.perf.NormalStopwatch; +import org.apache.hugegraph.perf.Stopwatch; +import org.apache.hugegraph.perf.Stopwatch.Path; +import org.apache.hugegraph.unit.BaseUnitTest; + +public class StopwatchTest extends BaseUnitTest { + + @Test + public void testNormalStopwatchChild() { + Stopwatch watch1 = new NormalStopwatch("w1", Path.EMPTY); + + Stopwatch watch2 = new NormalStopwatch("w2", watch1); + Stopwatch watch3 = new NormalStopwatch("w3", watch1); + Stopwatch watch4 = new NormalStopwatch("w4", watch1); + Stopwatch watch5 = new NormalStopwatch("w5", watch1); + + Assert.assertEquals(watch2, watch1.child("w2")); + Assert.assertEquals(watch3, watch1.child("w3")); + Assert.assertEquals(watch4, watch1.child("w4")); + Assert.assertEquals(watch5, watch1.child("w5")); + + Assert.assertEquals(watch2, watch1.child("w2", null)); + Assert.assertEquals(watch3, watch1.child("w3", null)); + Assert.assertEquals(watch4, watch1.child("w4", null)); + Assert.assertEquals(watch5, watch1.child("w5", null)); + + Assert.assertNull(watch1.child("w2")); + Assert.assertNull(watch1.child("w3")); + Assert.assertNull(watch1.child("w4")); + Assert.assertNull(watch1.child("w5")); + + Assert.assertNull(watch1.child("w2", watch2)); + Assert.assertNull(watch1.child("w3", watch3)); + Assert.assertNull(watch1.child("w4", watch4)); + Assert.assertNull(watch1.child("w5", watch5)); + + watch1.clear(); + Assert.assertNull(watch1.child("w2")); + Assert.assertNull(watch1.child("w3")); + Assert.assertNull(watch1.child("w4")); + Assert.assertNull(watch1.child("w5")); + } + + @Test + public void testLightStopwatchChild() { + Stopwatch watch1 = new LightStopwatch("w1", Path.EMPTY); + + Stopwatch watch2 = new LightStopwatch("w2", watch1); + Stopwatch watch3 = new LightStopwatch("w3", watch1); + Stopwatch watch4 = new LightStopwatch("w4", watch1); + Stopwatch watch5 = new LightStopwatch("w5", watch1); + + Assert.assertEquals(watch2, watch1.child("w2")); + Assert.assertEquals(watch3, watch1.child("w3")); + Assert.assertEquals(watch4, watch1.child("w4")); + Assert.assertEquals(watch5, watch1.child("w5")); + + Assert.assertEquals(watch2, watch1.child("w2", null)); + Assert.assertEquals(watch3, watch1.child("w3", null)); + Assert.assertEquals(watch4, watch1.child("w4", null)); + Assert.assertEquals(watch5, watch1.child("w5", null)); + + Assert.assertNull(watch1.child("w2")); + Assert.assertNull(watch1.child("w3")); + Assert.assertNull(watch1.child("w4")); + Assert.assertNull(watch1.child("w5")); + + Assert.assertNull(watch1.child("w2", watch2)); + Assert.assertNull(watch1.child("w3", watch3)); + Assert.assertNull(watch1.child("w4", watch4)); + Assert.assertNull(watch1.child("w5", watch5)); + + watch1.clear(); + Assert.assertNull(watch1.child("w2")); + Assert.assertNull(watch1.child("w3")); + Assert.assertNull(watch1.child("w4")); + Assert.assertNull(watch1.child("w5")); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestClass.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestClass.java new file mode 100644 index 0000000000..fcc90b9813 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestClass.java @@ -0,0 +1,105 @@ +/* + * 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.unit.perf.testclass; + +import org.apache.hugegraph.perf.PerfUtil; +import org.apache.hugegraph.perf.PerfUtil.Watched; + +public class TestClass { + + @Watched + public void test() { + new Foo().bar(); + } + + public static class Foo { + + @Watched(prefix="foo") + public void foo() { + this.bar(); + } + + @Watched(prefix="foo") + public void bar() {} + } + + public static class Bar { + + @Watched("bar_foo") + public void foo() { + this.bar(); + } + + @Watched("bar_bar") + public void bar() {} + } + + public static class ManuallyProfile { + + public void foo() { + PerfUtil.instance().start("manu-foo"); + this.bar(); + this.bar2(); + PerfUtil.instance().end("manu-foo"); + } + + public void bar() { + PerfUtil.instance().start("manu-bar"); + try { + Thread.sleep(0); + } catch (InterruptedException ignored) { + // pass + } + PerfUtil.instance().end("manu-bar"); + } + + public void foo2() { + PerfUtil.instance().start2("manu-foo2"); + this.bar(); + this.bar2(); + PerfUtil.instance().end("manu-foo2"); + } + + public void bar2() { + PerfUtil.instance().start2("manu-bar2"); + try { + Thread.sleep(0); + } catch (InterruptedException ignored) { + // pass + } + PerfUtil.instance().end("manu-bar2"); + } + } + + public static class Base { + + @Watched + public void func() {} + } + + public static class Sub extends Base { + + @Watched + public void func1() {} + + public void func2() {} + + @Watched + public void func3() {} + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestLightClass.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestLightClass.java new file mode 100644 index 0000000000..fd2e334bad --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestLightClass.java @@ -0,0 +1,50 @@ +/* + * 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.unit.perf.testclass; + +import org.apache.hugegraph.perf.PerfUtil.Watched; + +public class TestLightClass { + + @Watched + public void test() { + new Foo().bar(); + } + + public static class Foo { + + @Watched(prefix="foo") + public void foo() { + this.bar(); + } + + @Watched(prefix="foo") + public void bar() {} + } + + public static class Bar { + + @Watched(prefix="bar") + public void foo() { + this.bar(); + } + + @Watched(prefix="bar") + public void bar() {} + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestPerfClass.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestPerfClass.java new file mode 100644 index 0000000000..a9146f727e --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestPerfClass.java @@ -0,0 +1,72 @@ +/* + * 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.unit.perf.testclass; + +import org.apache.hugegraph.perf.PerfUtil.Watched; + +public class TestPerfClass { + + private Foo foo = new Foo(); + + @Watched + public void test(int times) { + for (int i = 0; i < times; i++) { + this.testNew(); + this.testNewAndCall(); + this.testCall(); + this.testCallFooThenSum(); + } + } + + @Watched + public void testNew() { + new Foo(); + } + + @Watched + public void testNewAndCall() { + new Foo().sum(1, 2); + } + + @Watched + public void testCall() { + this.foo.sum(1, 2); + } + + @Watched + public void testCallFooThenSum() { + this.foo.foo(); + } + + public static class Foo { + + @Watched + public void foo() { + this.sum(1, 2); + } + + @Watched + public int sum(int a, int b) { + int sum = a; + for (int i = 0; i < 100; i++) { + sum += i; + } + return sum + b; + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestPerfLightClass.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestPerfLightClass.java new file mode 100644 index 0000000000..430b9ac97a --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass/TestPerfLightClass.java @@ -0,0 +1,72 @@ +/* + * 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.unit.perf.testclass; + +import org.apache.hugegraph.perf.PerfUtil.Watched; + +public class TestPerfLightClass { + + private final Foo foo = new Foo(); + + @Watched + public void test(int times) { + for (int i = 0; i < times; i++) { + this.testNew(); + this.testNewAndCall(); + this.testCall(); + this.testCallFooThenSum(); + } + } + + @Watched + public void testNew() { + new Foo(); + } + + @Watched + public void testNewAndCall() { + new Foo().sum(1, 2); + } + + @Watched + public void testCall() { + this.foo.sum(1, 2); + } + + @Watched + public void testCallFooThenSum() { + this.foo.foo(); + } + + public static class Foo { + + @Watched + public void foo() { + this.sum(1, 2); + } + + @Watched + public int sum(int a, int b) { + int sum = a; + for (int i = 0; i < 100; i++) { + sum += i; + } + return sum + b; + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass2/TestClass4Package.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass2/TestClass4Package.java new file mode 100644 index 0000000000..9a29c2ab56 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/perf/testclass2/TestClass4Package.java @@ -0,0 +1,69 @@ +/* + * 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.unit.perf.testclass2; + +import org.apache.hugegraph.perf.PerfUtil.Watched; + +public class TestClass4Package { + + @Watched + public void test() { + new Foo().bar(); + } + + public static class Foo extends FooBase { + + @Watched + public void foo() { + this.bar(); + } + + @Watched + public void bar() {} + } + + public static class FooBase {} + + public static class Bar { + + @Watched + public void foo() { + this.bar(); + } + + @Watched + public void bar() {} + } + + public static class Base { + + @Watched + public void func() {} + } + + public static class Sub extends Base { + + @Watched + public void func1() {} + + public void func2() {} + + @Watched + public void func3() {} + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/AbstractRestClientTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/AbstractRestClientTest.java new file mode 100644 index 0000000000..b2d2b1a3bc --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/AbstractRestClientTest.java @@ -0,0 +1,57 @@ +/* + * 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.unit.rest; + +import org.apache.hugegraph.rest.AbstractRestClient; +import org.junit.Assert; +import org.junit.Test; + +public class AbstractRestClientTest { + + @Test + public void testEncodeWithSpaces() { + String raw = "hello world"; + String expected = "hello%2Bworld"; + String encoded = AbstractRestClient.encode(raw); + Assert.assertEquals(expected, encoded); + } + + @Test + public void testEncodeWithSpecialCharacters() { + String raw = "hello@world!"; + String expected = "hello%40world%21"; + String encoded = AbstractRestClient.encode(raw); + Assert.assertEquals(expected, encoded); + } + + @Test + public void testEncodeWithChineseCharacters() { + String raw = "你好"; + String expected = "%E4%BD%A0%E5%A5%BD"; + String encoded = AbstractRestClient.encode(raw); + Assert.assertEquals(expected, encoded); + } + + @Test + public void testEncodeWithNullInput() { + String raw = null; + Assert.assertThrows(NullPointerException.class, () -> { + AbstractRestClient.encode(raw); + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/RestClientTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/RestClientTest.java new file mode 100644 index 0000000000..712aea7ab2 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/RestClientTest.java @@ -0,0 +1,521 @@ +/* + * 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.unit.rest; + +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.function.BiFunction; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSessionContext; + +import org.apache.hugegraph.rest.AbstractRestClient; +import org.apache.hugegraph.rest.ClientException; +import org.apache.hugegraph.rest.RestClient; +import org.apache.hugegraph.rest.RestClientConfig; +import org.apache.hugegraph.rest.RestHeaders; +import org.apache.hugegraph.rest.RestResult; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.testutil.Whitebox; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.junit.Test; +import org.mockito.Mockito; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.net.HttpHeaders; + +import lombok.SneakyThrows; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class RestClientTest { + + private static final String TEST_URL = "http://localhost:8080"; + + @Test + public void testPost() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.post("path", "body"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + // TODO: How to verify it? + public void testPostWithMaxConnsAndPerRoute() { + RestClientConfig restClientConfig = + RestClientConfig.builder().timeout(1000).maxConns(10).maxConnsPerRoute(5).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.post("path", "body"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testPostWithUserAndPassword() { + RestClientConfig restClientConfig = + RestClientConfig.builder().user("user").password("").timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.post("path", "body"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testPostWithToken() { + RestClientConfig restClientConfig = + RestClientConfig.builder().token("token").timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.post("path", "body"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testPostWithAllParams() { + RestClientConfig restClientConfig = + RestClientConfig.builder().user("user").password("").timeout(1000).maxConns(10) + .maxConnsPerRoute(5).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.post("path", "body"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testPostWithTokenAndAllParams() { + RestClientConfig restClientConfig = + RestClientConfig.builder().token("token").timeout(1000).maxConns(10) + .maxConnsPerRoute(5).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.post("path", "body"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testPostHttpsWithAllParams() { + String url = "https://github.com/apache/incubator-hugegraph-doc/" + + "raw/master/dist/commons/cacerts.jks"; + String trustStoreFile = "src/test/resources/cacerts.jks"; + BaseUnitTest.downloadFileByUrl(url, trustStoreFile); + + String trustStorePassword = "changeit"; + RestClientConfig restClientConfig = + RestClientConfig.builder().user("user").password("").timeout(1000).maxConns(10) + .maxConnsPerRoute(5).trustStoreFile(trustStoreFile) + .trustStorePassword(trustStorePassword).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.post("path", "body"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testPostHttpsWithTokenAndAllParams() { + String url = "https://github.com/apache/incubator-hugegraph-doc/" + + "raw/master/dist/commons/cacerts.jks"; + String trustStoreFile = "src/test/resources/cacerts.jks"; + BaseUnitTest.downloadFileByUrl(url, trustStoreFile); + + String trustStorePassword = "changeit"; + RestClientConfig restClientConfig = + RestClientConfig.builder().token("token").timeout(1000).maxConns(10) + .maxConnsPerRoute(5).trustStoreFile(trustStoreFile) + .trustStorePassword(trustStorePassword).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.post("path", "body"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testHostNameVerifier() { + BiFunction verifer = (url, hostname) -> { + AbstractRestClient.HostNameVerifier verifier; + SSLSession session; + try { + SSLSessionContext sc = SSLContext.getDefault() + .getClientSessionContext(); + session = sc.getSession(new byte[]{11}); + verifier = new AbstractRestClient.HostNameVerifier(url); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + return verifier.verify(hostname, session); + }; + + Assert.assertTrue(verifer.apply("http://baidu.com", "baidu.com")); + Assert.assertTrue(verifer.apply("http://test1.baidu.com", "baidu.com")); + Assert.assertTrue(verifer.apply("http://test2.baidu.com", "baidu.com")); + Assert.assertFalse(verifer.apply("http://baidu2.com", "baidu.com")); + Assert.assertTrue(verifer.apply("http://baidu.com", "")); + Assert.assertTrue(verifer.apply("baidu.com", "baidu.com")); + Assert.assertTrue(verifer.apply("http://baidu.com/test", "baidu.com")); + Assert.assertTrue(verifer.apply("baidu.com/test/abc", "baidu.com")); + Assert.assertFalse(verifer.apply("baidu.com.sina.com", "baidu.com")); + } + + @Test + public void testPostWithHeaderAndContent() { + RestHeaders headers = new RestHeaders().add("key1", "value1-1") + .add("key1", "value1-2") + .add("Content-Encoding", "gzip"); + String content = "{\"names\": [\"marko\", \"josh\", \"lop\"]}"; + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200, headers, content); + RestResult restResult = client.post("path", "body"); + Assert.assertEquals(200, restResult.status()); + Assert.assertEquals(headers, restResult.headers()); + Assert.assertEquals(content, restResult.content()); + Assert.assertEquals(ImmutableList.of("marko", "josh", "lop"), + restResult.readList("names", String.class)); + } + + @Test + public void testPostWithException() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 400); + Assert.assertThrows(ClientException.class, () -> { + client.post("path", "body"); + }); + } + + @Test + public void testPostWithParams() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestHeaders headers = new RestHeaders(); + + Map params = ImmutableMap.of("param1", "value1"); + RestResult restResult = client.post("path", "body", headers, + params); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testPut() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.put("path", "id1", "body"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testPutWithHeaders() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestHeaders headers = new RestHeaders().add("key1", "value1-1") + .add("key2", "value1-2") + .add("Content-Encoding", "gzip"); + RestResult restResult = client.put("path", "id1", "body", headers); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testPutWithParams() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + Map params = ImmutableMap.of("param1", "value1"); + RestResult restResult = client.put("path", "id1", "body", params); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testPutWithException() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 400); + Assert.assertThrows(ClientException.class, () -> { + client.put("path", "id1", "body"); + }); + } + + @Test + public void testGet() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.get("path"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testGetWithId() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + RestResult restResult = client.get("path", "id1"); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testGetWithParams() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 200); + Map params = new HashMap<>(); + params.put("key1", ImmutableList.of("value1-1", "value1-2")); + params.put("key2", "value2"); + RestResult restResult = client.get("path", params); + Assert.assertEquals(200, restResult.status()); + } + + @Test + public void testGetWithException() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 400); + Assert.assertThrows(ClientException.class, () -> { + client.get("path", "id1"); + }); + } + + @Test + public void testDeleteWithId() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 204); + RestResult restResult = client.delete("path", "id1"); + Assert.assertEquals(204, restResult.status()); + } + + @Test + public void testDeleteWithParams() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 204); + Map params = ImmutableMap.of("param1", "value1"); + RestResult restResult = client.delete("path", params); + Assert.assertEquals(204, restResult.status()); + } + + @Test + public void testDeleteWithException() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClient client = new RestClientImpl(TEST_URL, restClientConfig, 400); + Assert.assertThrows(ClientException.class, () -> { + client.delete("path", "id1"); + }); + } + + @Test + public void testAuthContext() { + RestClientConfig restClientConfig = RestClientConfig.builder().timeout(1000).build(); + RestClientImpl client = new RestClientImpl(TEST_URL, restClientConfig, 200); + Assert.assertNull(client.getAuthContext()); + + String token = UUID.randomUUID().toString(); + client.setAuthContext(token); + Assert.assertEquals(token, client.getAuthContext()); + + client.resetAuthContext(); + Assert.assertNull(client.getAuthContext()); + } + + @SneakyThrows + @Test + public void testBuilderCallback() { + // default configs + MockRestClientImpl restClient = new MockRestClientImpl(TEST_URL, + RestClientConfig.builder().build()); + OkHttpClient okHttpClient = Whitebox.getInternalState(restClient, "client"); + Assert.assertEquals(okHttpClient.connectTimeoutMillis(), 10000); + Assert.assertEquals(okHttpClient.readTimeoutMillis(), 10000); + + // set config by (user)builderCallback + RestClientConfig config = RestClientConfig.builder().builderCallback( + builder -> builder.connectTimeout(5, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS)) + .build(); + + restClient = new MockRestClientImpl(TEST_URL, config); + okHttpClient = Whitebox.getInternalState(restClient, "client"); + + Assert.assertEquals(okHttpClient.connectTimeoutMillis(), 5000); + Assert.assertEquals(okHttpClient.readTimeoutMillis(), 30000); + } + + @SneakyThrows + @Test + public void testRequest() { + Response response = Mockito.mock(Response.class, Mockito.RETURNS_DEEP_STUBS); + Mockito.when(response.code()).thenReturn(200); + Mockito.when(response.headers()) + .thenReturn(new RestHeaders().toOkHttpHeader()); + Mockito.when(response.body().string()).thenReturn("content"); + + Request.Builder requestBuilder = Mockito.mock(Request.Builder.class, + Mockito.RETURNS_DEEP_STUBS); + Mockito.when(requestBuilder.delete()).thenReturn(requestBuilder); + Mockito.when(requestBuilder.get()).thenReturn(requestBuilder); + Mockito.when(requestBuilder.put(Mockito.any())).thenReturn(requestBuilder); + Mockito.when(requestBuilder.post(Mockito.any())).thenReturn(requestBuilder); + Mockito.when(requestBuilder.url((HttpUrl) Mockito.any())).thenReturn(requestBuilder); + MockRestClientImpl client = new MockRestClientImpl(TEST_URL, 1000) { + @Override + protected Request.Builder newRequestBuilder() { + return requestBuilder; + } + }; + + OkHttpClient okHttpClient = Mockito.mock(OkHttpClient.class, Mockito.RETURNS_DEEP_STUBS); + Mockito.when(okHttpClient.newCall(Mockito.any()).execute()).thenReturn(response); + + Whitebox.setInternalState(client, "client", okHttpClient); + + RestResult result; + + // Test delete + client.setAuthContext("token1"); + result = client.delete("test", ImmutableMap.of()); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(RestHeaders.AUTHORIZATION, "token1"); + + client.resetAuthContext(); + + client.setAuthContext("token2"); + result = client.delete("test", "id"); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token2"); + client.resetAuthContext(); + + // Test get + client.setAuthContext("token3"); + result = client.get("test"); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token3"); + client.resetAuthContext(); + + client.setAuthContext("token4"); + result = client.get("test", ImmutableMap.of()); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token4"); + client.resetAuthContext(); + + client.setAuthContext("token5"); + result = client.get("test", "id"); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token5"); + client.resetAuthContext(); + + // Test put + client.setAuthContext("token6"); + result = client.post("test", null); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token6"); + client.resetAuthContext(); + + client.setAuthContext("token7"); + result = client.post("test", null, new RestHeaders()); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token7"); + client.resetAuthContext(); + + client.setAuthContext("token8"); + result = client.post("test", null, ImmutableMap.of()); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token8"); + client.resetAuthContext(); + + client.setAuthContext("token9"); + result = client.post("test", null, new RestHeaders(), + ImmutableMap.of()); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token9"); + client.resetAuthContext(); + + // Test post + client.setAuthContext("token10"); + result = client.post("test", null); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token10"); + client.resetAuthContext(); + + client.setAuthContext("token11"); + result = client.post("test", null, new RestHeaders()); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token11"); + client.resetAuthContext(); + + client.setAuthContext("token12"); + result = client.post("test", null, ImmutableMap.of()); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token12"); + client.resetAuthContext(); + + client.setAuthContext("token13"); + result = client.post("test", null, new RestHeaders(), + ImmutableMap.of()); + Assert.assertEquals(200, result.status()); + Mockito.verify(requestBuilder).addHeader(HttpHeaders.AUTHORIZATION, "token13"); + client.resetAuthContext(); + } + + private static class RestClientImpl extends AbstractRestClient { + + private final int status; + private final RestHeaders headers; + private final String content; + + public RestClientImpl(String url, RestClientConfig config, int status) { + this(url, config, status, new RestHeaders(), ""); + } + + public RestClientImpl(String url, RestClientConfig config, int status, RestHeaders headers, + String content) { + super(url, config); + this.status = status; + this.headers = headers; + this.content = content; + } + + @SneakyThrows + @Override + protected Response request(Request.Builder requestBuilder) { + Response response = Mockito.mock(Response.class, Mockito.RETURNS_DEEP_STUBS); + Mockito.when(response.code()).thenReturn(this.status); + Mockito.when(response.headers()).thenReturn(this.headers.toOkHttpHeader()); + Mockito.when(response.body().string()).thenReturn(this.content); + return response; + } + + @Override + protected void checkStatus(Response response, int... statuses) { + boolean match = false; + for (int status : statuses) { + if (status == response.code()) { + match = true; + break; + } + } + if (!match) { + throw new ClientException("Invalid response '%s'", response); + } + } + } + + private static class MockRestClientImpl extends AbstractRestClient { + + public MockRestClientImpl(String url, int timeout) { + super(url, timeout); + } + + public MockRestClientImpl(String url, RestClientConfig config) { + super(url, config); + } + + @Override + protected void checkStatus(Response response, int... statuses) { + // pass + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/RestResultTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/RestResultTest.java new file mode 100644 index 0000000000..06eb03a11d --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/RestResultTest.java @@ -0,0 +1,141 @@ +/* + * 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.unit.rest; + +import java.util.Map; + +import org.apache.hugegraph.rest.RestHeaders; +import org.apache.hugegraph.rest.RestResult; +import org.apache.hugegraph.rest.SerializeException; +import org.apache.hugegraph.testutil.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import lombok.SneakyThrows; +import okhttp3.Response; + +public class RestResultTest { + + private static RestResult newRestResult(int status) { + return newRestResult(status, "", new RestHeaders()); + } + + private static RestResult newRestResult(int status, String content) { + return newRestResult(status, content, new RestHeaders()); + } + + private static RestResult newRestResult(int status, RestHeaders headers) { + return newRestResult(status, "", headers); + } + + @SneakyThrows + private static RestResult newRestResult(int status, String content, + RestHeaders headers) { + Response response = Mockito.mock(Response.class, Mockito.RETURNS_DEEP_STUBS); + Mockito.when(response.code()).thenReturn(status); + Mockito.when(response.headers()).thenReturn(headers.toOkHttpHeader()); + Mockito.when(response.body().string()) + .thenReturn(content); + return new RestResult(response); + } + + @Test + public void testStatus() { + RestResult result = newRestResult(200); + Assert.assertEquals(200, result.status()); + } + + @Test + public void testHeaders() { + RestHeaders headers = new RestHeaders(); + headers.add("key1", "value1-1"); + headers.add("key1", "value1-2"); + headers.add("key2", "value2"); + RestResult result = newRestResult(200, headers); + Assert.assertEquals(200, result.status()); + Assert.assertEquals(headers, result.headers()); + } + + @Test + public void testContent() { + String content = "{\"name\": \"marko\"}"; + RestResult result = newRestResult(200, content); + Assert.assertEquals(200, result.status()); + Assert.assertEquals(content, result.content()); + Assert.assertEquals(ImmutableMap.of("name", "marko"), + result.readObject(Map.class)); + } + + @Test + public void testContentWithException() { + String content = "{illegal key: \"marko\"}"; + RestResult result = newRestResult(200, content); + Assert.assertEquals(200, result.status()); + Assert.assertEquals(content, result.content()); + Assert.assertThrows(SerializeException.class, () -> { + result.readObject(Map.class); + }); + } + + @Test + public void testContentList() { + String content = "{\"names\": [\"marko\", \"josh\", \"lop\"]}"; + RestResult result = newRestResult(200, content); + Assert.assertEquals(200, result.status()); + Assert.assertEquals(content, result.content()); + Assert.assertEquals(ImmutableList.of("marko", "josh", "lop"), + result.readList("names", String.class)); + + content = "[\"marko\", \"josh\", \"lop\"]"; + result = newRestResult(200, content); + Assert.assertEquals(200, result.status()); + Assert.assertEquals(content, result.content()); + Assert.assertEquals(ImmutableList.of("marko", "josh", "lop"), + result.readList(String.class)); + } + + @Test + public void testContentListWithException() { + String content = "{\"names\": [\"marko\", \"josh\", \"lop\"]}"; + RestResult result = newRestResult(200, content); + Assert.assertEquals(200, result.status()); + Assert.assertEquals(content, result.content()); + Assert.assertThrows(SerializeException.class, () -> { + result.readList("unexitsed key", String.class); + }); + + content = "{\"names\": [marko, josh, \"lop\"]}"; + RestResult result2 = newRestResult(200, content); + Assert.assertEquals(200, result2.status()); + Assert.assertEquals(content, result2.content()); + Assert.assertThrows(SerializeException.class, () -> { + result2.readList("names", String.class); + }); + + content = "[marko, josh, \"lop\"]"; + RestResult result3 = newRestResult(200, content); + Assert.assertEquals(200, result3.status()); + Assert.assertEquals(content, result3.content()); + Assert.assertThrows(SerializeException.class, () -> { + result3.readList(String.class); + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/BytesTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/BytesTest.java new file mode 100644 index 0000000000..7ecc59cbd0 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/BytesTest.java @@ -0,0 +1,169 @@ +/* + * 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.unit.util; + +import org.junit.Test; + +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.util.Bytes; +import org.apache.hugegraph.util.NumericUtil; +import org.apache.hugegraph.testutil.Assert; + +public class BytesTest extends BaseUnitTest { + + @Test + public void testBytesEquals() { + Assert.assertTrue(Bytes.equals(b("12345678"), + b("12345678"))); + Assert.assertTrue(Bytes.equals(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 5, 7})); + + Assert.assertFalse(Bytes.equals(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 6, 7})); + Assert.assertFalse(Bytes.equals(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 5, 7, 0})); + } + + @Test + public void testBytesPrefixWith() { + Assert.assertTrue(Bytes.prefixWith(b("12345678"), b("12345678"))); + Assert.assertTrue(Bytes.prefixWith(b("12345678"), b("1234567"))); + + Assert.assertTrue(Bytes.prefixWith(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 5, 7})); + Assert.assertTrue(Bytes.prefixWith(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 5})); + Assert.assertTrue(Bytes.prefixWith(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3})); + + Assert.assertFalse(Bytes.prefixWith(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 6, 6})); + Assert.assertFalse(Bytes.prefixWith(new byte[]{1, 3, 5, 7}, + new byte[]{3, 1})); + Assert.assertFalse(Bytes.prefixWith(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 5, 7, 0})); + } + + @Test + public void testBytesCompare() { + Assert.assertEquals(0, Bytes.compare(b("12345678"), b("12345678"))); + Assert.assertTrue(Bytes.compare(b("12345678"), b("1234567")) > 0); + Assert.assertTrue(Bytes.compare(b("12345678"), b("12345679")) < 0); + + Assert.assertEquals(0, + Bytes.compare(new byte[]{1, 3, 5, 7}, new byte[]{1, 3, 5, 7})); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 5, 6}) > 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 5}) > 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 0}, + new byte[]{1, 3, 5}) > 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3}) > 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 6, 0}) < 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7}, + new byte[]{1, 4}) < 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7}, + new byte[]{3, 1}) < 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 5, 7, 0}) < 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7}, + new byte[]{1, 3, 5, -1}) < 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 0}, + new byte[]{1, 3, 5, -128}) < 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, -2}, + new byte[]{1, 3, 5, -1}) < 0); + + Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, -128}, + new byte[]{1, 3, 5, -1}) < 0); + } + + @Test + public void testBytesConcat() { + Assert.assertArrayEquals(b("12345678"), + Bytes.concat(b("1234"), b("5678"))); + Assert.assertArrayEquals(b("12345678"), + Bytes.concat(b("12345678"), b(""))); + Assert.assertArrayEquals(b("12345678"), + Bytes.concat(b(""), b("12345678"))); + } + + @Test + public void testBytesContains() { + Assert.assertTrue(Bytes.contains(b("1234"), (byte) '1')); + Assert.assertTrue(Bytes.contains(b("1234"), (byte) '3')); + Assert.assertTrue(Bytes.contains(b("1234"), (byte) '4')); + + Assert.assertFalse(Bytes.contains(b("1234"), (byte) '0')); + Assert.assertFalse(Bytes.contains(b(""), (byte) '0')); + } + + @Test + public void testBytesIndexOf() { + Assert.assertEquals(0, Bytes.indexOf(b("1234"), (byte) '1')); + Assert.assertEquals(2, Bytes.indexOf(b("1234"), (byte) '3')); + Assert.assertEquals(3, Bytes.indexOf(b("1234"), (byte) '4')); + + Assert.assertEquals(-1, Bytes.indexOf(b("1234"), (byte) '0')); + Assert.assertEquals(-1, Bytes.indexOf(b(""), (byte) '0')); + } + + @Test + public void testByteToHex() { + byte value = 0; + Assert.assertEquals("00", Bytes.toHex(value)); + + value = 127; + Assert.assertEquals("7f", Bytes.toHex(value)); + + value = -128; + Assert.assertEquals("80", Bytes.toHex(value)); + + value = -1; + Assert.assertEquals("ff", Bytes.toHex(value)); + } + + @Test + public void testBytesToHex() { + int value = 0x0103807f; + byte[] bytes = NumericUtil.intToBytes(value); + Assert.assertEquals("0103807f", Bytes.toHex(bytes)); + } + + @Test + public void testBytesFromHex() { + Assert.assertEquals(0x0103807f, + NumericUtil.bytesToInt(Bytes.fromHex("0103807f"))); + } + + private static byte[] b(String string) { + return string.getBytes(); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/CollectionUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/CollectionUtilTest.java new file mode 100644 index 0000000000..71a440cd23 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/CollectionUtilTest.java @@ -0,0 +1,572 @@ +/* + * 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.unit.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Test; + +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.util.CollectionUtil; +import org.apache.hugegraph.testutil.Assert; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +public class CollectionUtilTest extends BaseUnitTest { + + @Test + public void testToSet() { + Assert.assertThrows(NullPointerException.class, () -> { + CollectionUtil.toSet(null); + }); + + Object array1 = new Integer[]{1, 2, 3}; + Assert.assertEquals(ImmutableSet.of(1, 2, 3), + CollectionUtil.toSet(array1)); + + Object array2 = new String[]{"1", "2", "3"}; + Assert.assertEquals(ImmutableSet.of("1", "2", "3"), + CollectionUtil.toSet(array2)); + + Set set = ImmutableSet.of(1, 2, 3); + Assert.assertEquals(ImmutableSet.of(1, 2, 3), + CollectionUtil.toSet(set)); + + List list = ImmutableList.of(1, 2, 3); + Assert.assertEquals(ImmutableSet.of(1, 2, 3), + CollectionUtil.toSet(list)); + + Assert.assertEquals(ImmutableSet.of(1), CollectionUtil.toSet(1)); + } + + @Test + public void testToList() { + Assert.assertThrows(NullPointerException.class, () -> { + CollectionUtil.toList(null); + }); + + Object array1 = new Integer[]{1, 2, 3}; + Assert.assertEquals(ImmutableList.of(1, 2, 3), + CollectionUtil.toList(array1)); + + Object array2 = new String[]{"1", "2", "3"}; + Assert.assertEquals(ImmutableList.of("1", "2", "3"), + CollectionUtil.toList(array2)); + + Set set = ImmutableSet.of(1, 2, 3); + Assert.assertEquals(ImmutableList.of(1, 2, 3), + CollectionUtil.toList(set)); + + List list = ImmutableList.of(1, 2, 3); + Assert.assertEquals(ImmutableList.of(1, 2, 3), + CollectionUtil.toList(list)); + + Assert.assertEquals(ImmutableList.of("123"), + CollectionUtil.toList("123")); + } + + @Test + public void testPrefixOf() { + List list = ImmutableList.of(1, 2, 3); + + List list1 = ImmutableList.of(); + Assert.assertTrue(CollectionUtil.prefixOf(list1, list)); + + List list2 = ImmutableList.of(1, 2); + Assert.assertTrue(CollectionUtil.prefixOf(list2, list)); + + List list3 = ImmutableList.of(1, 2, 3); + Assert.assertTrue(CollectionUtil.prefixOf(list3, list)); + + List list4 = ImmutableList.of(1, 2, 3, 4); + Assert.assertFalse(CollectionUtil.prefixOf(list4, list)); + + List list5 = ImmutableList.of(1, 2, 4); + Assert.assertFalse(CollectionUtil.prefixOf(list5, list)); + + List list6 = Arrays.asList(1, 2, null); + Assert.assertFalse(CollectionUtil.prefixOf(list6, list)); + } + + @Test + public void testRandomSet() { + Set set = CollectionUtil.randomSet(0, 100, 10); + for (int i : set) { + Assert.assertTrue(0 <= i && i < 100); + } + + // invalid min + Assert.assertThrows(IllegalArgumentException.class, () -> { + CollectionUtil.randomSet(200, 100, 10); + }); + + // invalid count = 0 + Assert.assertThrows(IllegalArgumentException.class, () -> { + CollectionUtil.randomSet(1, 100, 0); + }); + + // invalid count > max - min + Assert.assertThrows(IllegalArgumentException.class, () -> { + CollectionUtil.randomSet(1, 100, 100); + }); + } + + @Test + public void testAllUnique() { + List list = ImmutableList.of(); + Assert.assertTrue(CollectionUtil.allUnique(list)); + + list = ImmutableList.of(1, 2, 3, 2, 3); + Assert.assertFalse(CollectionUtil.allUnique(list)); + + list = ImmutableList.of(1, 2, 3, 4, 5); + Assert.assertTrue(CollectionUtil.allUnique(list)); + + list = ImmutableList.of(1, 1, 1, 1, 1); + Assert.assertFalse(CollectionUtil.allUnique(list)); + } + + @Test + public void testSubSet() { + Set originSet = ImmutableSet.of(1, 2, 3, 4, 5); + + Set subSet = CollectionUtil.subSet(originSet, 1, 1); + Assert.assertEquals(ImmutableSet.of(), subSet); + + subSet = CollectionUtil.subSet(originSet, 2, 4); + Assert.assertEquals(ImmutableSet.of(3, 4), subSet); + + subSet = CollectionUtil.subSet(originSet, 2, 5); + Assert.assertEquals(ImmutableSet.of(3, 4, 5), subSet); + + subSet = CollectionUtil.subSet(originSet, 0, 5); + Assert.assertEquals(ImmutableSet.of(1, 2, 3, 4, 5), subSet); + + subSet = CollectionUtil.subSet(originSet, 2, -1); + Assert.assertEquals(ImmutableSet.of(3, 4, 5), subSet); + + subSet = CollectionUtil.subSet(originSet, 2, -100); + Assert.assertEquals(ImmutableSet.of(3, 4, 5), subSet); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + CollectionUtil.subSet(originSet, 2, 1); + }, e -> { + Assert.assertContains("Invalid to parameter ", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + CollectionUtil.subSet(originSet, -1, 2); + }, e -> { + Assert.assertContains("Invalid from parameter ", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + CollectionUtil.subSet(originSet, -10, 2); + }, e -> { + Assert.assertContains("Invalid from parameter ", e.getMessage()); + }); + } + + @Test + public void testUnion() { + List first = new ArrayList<>(); + first.add(1); + first.add(2); + + Set second = new HashSet<>(); + second.add(1); + second.add(3); + + Set results = CollectionUtil.union(first, second); + Assert.assertEquals(3, results.size()); + } + + @Test + public void testIntersectWithoutModifying() { + List first = new ArrayList<>(); + first.add(1); + first.add(2); + first.add(3); + + List second = new ArrayList<>(); + second.add(4); + second.add(5); + + Collection results = CollectionUtil.intersect(first, second); + Assert.assertEquals(0, results.size()); + Assert.assertEquals(3, first.size()); + + second.add(3); + results = CollectionUtil.intersect(first, second); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(3, first.size()); + + second.add(1); + second.add(2); + results = CollectionUtil.intersect(first, second); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(3, first.size()); + + Set set = new HashSet<>(); + set.add(1); + set.add(3); + set.add(6); + + results = CollectionUtil.intersect(set, second); + Assert.assertInstanceOf(HashSet.class, results); + Assert.assertEquals(2, results.size()); + Assert.assertEquals(3, set.size()); + + set = new LinkedHashSet<>(); + set.add(1); + set.add(2); + set.add(6); + + results = CollectionUtil.intersect(set, second); + Assert.assertInstanceOf(LinkedHashSet.class, results); + Assert.assertEquals(2, results.size()); + Assert.assertEquals(3, set.size()); + } + + @Test + public void testIntersectWithModifying() { + Set first = new HashSet<>(); + first.add(1); + first.add(2); + first.add(3); + + Set second = new HashSet<>(); + second.add(1); + second.add(2); + second.add(3); + + Collection results = CollectionUtil.intersectWithModify( + first, second); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(3, first.size()); + + // The second set has "1", "2" + second.remove(3); + results = CollectionUtil.intersectWithModify(first, second); + Assert.assertEquals(2, results.size()); + Assert.assertEquals(2, first.size()); + + // The second set is empty + second.remove(1); + second.remove(2); + results = CollectionUtil.intersectWithModify(first, second); + Assert.assertEquals(0, results.size()); + Assert.assertEquals(0, first.size()); + } + + @Test + public void testHasIntersectionBetweenListAndSet() { + List first = new ArrayList<>(); + first.add(1); + first.add(2); + first.add(3); + + Set second = new HashSet<>(); + Assert.assertFalse(CollectionUtil.hasIntersection(first, second)); + + second.add(4); + Assert.assertFalse(CollectionUtil.hasIntersection(first, second)); + + second.add(1); + Assert.assertTrue(CollectionUtil.hasIntersection(first, second)); + + second = new HashSet<>(); + second.add(4); + second.add(5); + second.add(6); + second.add(7); + Assert.assertFalse(CollectionUtil.hasIntersection(first, second)); + + second.add(3); + Assert.assertTrue(CollectionUtil.hasIntersection(first, second)); + } + + @Test + public void testHasIntersectionBetweenSetAndSet() { + Set first = new HashSet<>(); + first.add(1); + first.add(2); + first.add(3); + + Set second = new HashSet<>(); + Assert.assertFalse(CollectionUtil.hasIntersection(first, second)); + + second.add(4); + Assert.assertFalse(CollectionUtil.hasIntersection(first, second)); + + second.add(1); + Assert.assertTrue(CollectionUtil.hasIntersection(first, second)); + + second = new HashSet<>(); + second.add(4); + second.add(5); + second.add(6); + second.add(7); + Assert.assertFalse(CollectionUtil.hasIntersection(first, second)); + + second.add(3); + Assert.assertTrue(CollectionUtil.hasIntersection(first, second)); + } + + @Test + public void testMapSortByStringKey() { + Map unordered = new HashMap<>(); + unordered.put("D", 1); + unordered.put("B", 2); + unordered.put("E", 3); + unordered.put("A", 4); + unordered.put("C", 5); + + Map incrOrdered = CollectionUtil.sortByKey(unordered, + true); + Assert.assertEquals(ImmutableList.of("A", "B", "C", "D", "E"), + ImmutableList.copyOf(incrOrdered.keySet())); + + Map decrOrdered = CollectionUtil.sortByKey(unordered, + false); + Assert.assertEquals(ImmutableList.of("E", "D", "C", "B", "A"), + ImmutableList.copyOf(decrOrdered.keySet())); + } + + @Test + public void testMapSortByIntegerKey() { + Map unordered = new HashMap<>(); + unordered.put(4, "A"); + unordered.put(2, "B"); + unordered.put(5, "C"); + unordered.put(1, "D"); + unordered.put(3, "E"); + + Map incrOrdered = CollectionUtil.sortByKey(unordered, + true); + Assert.assertEquals(ImmutableList.of(1, 2, 3, 4, 5), + ImmutableList.copyOf(incrOrdered.keySet())); + + Map decrOrdered = CollectionUtil.sortByKey(unordered, + false); + Assert.assertEquals(ImmutableList.of(5, 4, 3, 2, 1), + ImmutableList.copyOf(decrOrdered.keySet())); + } + + @Test + public void testMapSortByIntegerValue() { + Map unordered = new HashMap<>(); + unordered.put("A", 4); + unordered.put("B", 2); + unordered.put("C", 5); + unordered.put("D", 1); + unordered.put("E", 3); + + Map incrOrdered = CollectionUtil.sortByValue(unordered, + true); + Assert.assertEquals(ImmutableList.of(1, 2, 3, 4, 5), + ImmutableList.copyOf(incrOrdered.values())); + + Map decrOrdered = CollectionUtil.sortByValue(unordered, + false); + Assert.assertEquals(ImmutableList.of(5, 4, 3, 2, 1), + ImmutableList.copyOf(decrOrdered.values())); + } + + @Test + public void testMapSortByStringValue() { + Map unordered = new HashMap<>(); + unordered.put(1, "D"); + unordered.put(2, "B"); + unordered.put(3, "E"); + unordered.put(4, "A"); + unordered.put(5, "C"); + + Map incrOrdered = CollectionUtil.sortByValue(unordered, + true); + Assert.assertEquals(ImmutableList.of("A", "B", "C", "D", "E"), + ImmutableList.copyOf(incrOrdered.values())); + + Map decrOrdered = CollectionUtil.sortByValue(unordered, + false); + Assert.assertEquals(ImmutableList.of("E", "D", "C", "B", "A"), + ImmutableList.copyOf(decrOrdered.values())); + } + + @Test + public void testCrossCombineParts() { + List> parts; + + parts = ImmutableList.of(ImmutableList.of("a", "b"), + ImmutableList.of(1, 2), + ImmutableList.of('x', 'y')); + List> combs = CollectionUtil.crossCombineParts(parts); + Assert.assertEquals(8, combs.size()); + Assert.assertEquals(ImmutableList.of( + ImmutableList.of("a", "b", 1, 2, 'x', 'y'), + ImmutableList.of("a", "b", 1, 2, 'y', 'x'), + ImmutableList.of("a", "b", 2, 1, 'x', 'y'), + ImmutableList.of("a", "b", 2, 1, 'y', 'x'), + ImmutableList.of("b", "a", 1, 2, 'x', 'y'), + ImmutableList.of("b", "a", 1, 2, 'y', 'x'), + ImmutableList.of("b", "a", 2, 1, 'x', 'y'), + ImmutableList.of("b", "a", 2, 1, 'y', 'x')), + combs); + + parts = ImmutableList.of(ImmutableList.of("a", "b", "c"), + ImmutableList.of(1, 2), + ImmutableList.of('x', 'y')); + Assert.assertEquals(24, + CollectionUtil.crossCombineParts(parts).size()); + + parts = ImmutableList.of(ImmutableList.of("a", "b", "c"), + ImmutableList.of(1, 2, 3), + ImmutableList.of('x', 'y')); + Assert.assertEquals(72, + CollectionUtil.crossCombineParts(parts).size()); + + parts = ImmutableList.of(ImmutableList.of("a", "b", "c"), + ImmutableList.of(1, 2, 3), + ImmutableList.of('x', 'y', 'z')); + Assert.assertEquals(216, + CollectionUtil.crossCombineParts(parts).size()); + } + + @Test + public void testCnm() { + List list = ImmutableList.of(1, 2, 3, 4, 5); + + // Test C(5, 2) with all combinations + List> tuples = new ArrayList<>(); + boolean found; + found = CollectionUtil.cnm(list, list.size(), 2, tuple -> { + tuples.add(new ArrayList<>(tuple)); + return false; + }); + Assert.assertFalse(found); + Assert.assertEquals(10, tuples.size()); + + Assert.assertEquals(10, + CollectionUtil.cnm(list, list.size(), 2).size()); + + // Test C(5, 2) with one combination + tuples.clear(); + found = CollectionUtil.cnm(list, list.size(), 2, tuple -> { + if (tuple.equals(ImmutableList.of(2, 3))) { + tuples.add(new ArrayList<>(tuple)); + return true; + } + return false; + }); + Assert.assertTrue(found); + Assert.assertEquals(1, tuples.size()); + Assert.assertEquals(ImmutableList.of(2, 3), tuples.get(0)); + + // Test C(5, 3) with all combinations + List> triples = new ArrayList<>(); + found = CollectionUtil.cnm(list, list.size(), 3, triple -> { + triples.add(new ArrayList<>(triple)); + return false; + }); + Assert.assertFalse(found); + Assert.assertEquals(10, triples.size()); + + Assert.assertEquals(10, + CollectionUtil.cnm(list, list.size(), 3).size()); + + // Test C(5, 3) with one combination + triples.clear(); + found = CollectionUtil.cnm(list, list.size(), 3, triple -> { + if (triple.equals(ImmutableList.of(2, 3, 5))) { + triples.add(new ArrayList<>(triple)); + return true; + } + return false; + }); + Assert.assertTrue(found); + Assert.assertEquals(1, triples.size()); + Assert.assertEquals(ImmutableList.of(2, 3, 5), triples.get(0)); + } + + @Test + public void testAnm() { + List list = ImmutableList.of(1, 2, 3, 4, 5); + + // Test A(5, 5) with all combinations + Assert.assertEquals(120, CollectionUtil.anm(list).size()); + + // Test A(5, 2) with all combinations + List> tuples = new ArrayList<>(); + boolean found; + found = CollectionUtil.anm(list, list.size(), 2, tuple -> { + tuples.add(new ArrayList<>(tuple)); + return false; + }); + Assert.assertFalse(found); + Assert.assertEquals(20, tuples.size()); + + Assert.assertEquals(20, + CollectionUtil.anm(list, list.size(), 2).size()); + + // Test A(5, 2) with one combination + tuples.clear(); + found = CollectionUtil.anm(list, list.size(), 2, tuple -> { + if (tuple.equals(ImmutableList.of(2, 3))) { + tuples.add(new ArrayList<>(tuple)); + return true; + } + return false; + }); + Assert.assertTrue(found); + Assert.assertEquals(1, tuples.size()); + Assert.assertEquals(ImmutableList.of(2, 3), tuples.get(0)); + + // Test A(5, 3) with all combinations + List> triples = new ArrayList<>(); + found = CollectionUtil.anm(list, list.size(), 3, triple -> { + triples.add(new ArrayList<>(triple)); + return false; + }); + Assert.assertFalse(found); + Assert.assertEquals(60, triples.size()); + + Assert.assertEquals(60, + CollectionUtil.anm(list, list.size(), 3).size()); + + // Test A(5, 3) with one combination + triples.clear(); + found = CollectionUtil.anm(list, list.size(), 3, triple -> { + if (triple.equals(ImmutableList.of(2, 3, 5))) { + triples.add(new ArrayList<>(triple)); + return true; + } + return false; + }); + Assert.assertTrue(found); + Assert.assertEquals(1, triples.size()); + Assert.assertEquals(ImmutableList.of(2, 3, 5), triples.get(0)); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/DateUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/DateUtilTest.java new file mode 100644 index 0000000000..7c51406b36 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/DateUtilTest.java @@ -0,0 +1,126 @@ +/* + * 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.unit.util; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.Test; + +import org.apache.hugegraph.util.DateUtil; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; + +public class DateUtilTest extends BaseUnitTest { + + @Test + public void testParse() { + Date date1 = DateUtil.parse("2020-06-12 12:00:00"); + Date date2 = DateUtil.parse("2020-06-13"); + Assert.assertNotEquals(date1, date2); + Assert.assertTrue(date1.before(date2)); + + Date date3 = DateUtil.parse("2020-06-12"); + Date date4 = DateUtil.parse("2020-06-12 00:00:00.00"); + Assert.assertEquals(date3, date4); + + Date date5 = DateUtil.parse("2020-06-12 00:00:00.001"); + Assert.assertNotEquals(date3, date5); + Assert.assertTrue(date3.before(date5)); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + DateUtil.parse("2018-"); + }, e -> { + Assert.assertContains("Expected date format is:", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + DateUtil.parse("2018-15-07 12:00:00.f"); + }, e -> { + Assert.assertContains("Expected date format is:", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + DateUtil.parse("2018-15-07 12:00:00"); + }, e -> { + Assert.assertContains("Value 15 for monthOfYear must be " + + "in the range [1,12]", e.getMessage()); + }); + } + + @Test + public void testNow() { + Date date1 = DateUtil.now(); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // ignore + } + Date date2 = DateUtil.now(); + Assert.assertTrue(date1.before(date2)); + } + + @Test + public void testParseCornerDateValue() throws InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + int threadCount = 10; + List threads = new ArrayList<>(threadCount); + AtomicInteger errorCount = new AtomicInteger(0); + for (int t = 0; t < threadCount; t++) { + Thread thread = new Thread(() -> { + try { + latch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + try { + Assert.assertEquals(new Date(-62167248343000L), + DateUtil.parse("0", "yyyy")); + } catch (Exception e) { + errorCount.incrementAndGet(); + } + }); + threads.add(thread); + } + + for (Thread thread : threads) { + thread.start(); + } + latch.countDown(); + for (Thread thread : threads) { + thread.join(); + } + + Assert.assertEquals(0, errorCount.get()); + } + + @Test + public void testToPattern() { + Object pattern = DateUtil.toPattern("yyyyMMdd HH:mm:ss.SSS"); + Assert.assertEquals("yyyyMMdd HH:mm:ss.SSS", pattern); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + DateUtil.toPattern("iyyyyMMdd"); + }, e -> { + Assert.assertContains("Illegal pattern component: i", e.getMessage()); + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/EcheckTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/EcheckTest.java new file mode 100644 index 0000000000..c87bbf6271 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/EcheckTest.java @@ -0,0 +1,150 @@ +/* + * 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.unit.util; + +import org.junit.Test; + +import org.apache.hugegraph.util.E; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +public class EcheckTest extends BaseUnitTest { + + @Test + public void testCheckNotNull() { + E.checkNotNull(0, "test"); + E.checkNotNull(new Object(), "test"); + E.checkNotNull("1", "test"); + E.checkNotNull(ImmutableList.of(), "test"); + + Assert.assertThrows(NullPointerException.class, () -> { + E.checkNotNull(null, "test"); + }, e -> { + Assert.assertContains("The 'test' can't be null", e.getMessage()); + }); + + Assert.assertThrows(NullPointerException.class, () -> { + E.checkNotNull(null, "test2"); + }, e -> { + Assert.assertContains("The 'test2' can't be null", e.getMessage()); + }); + } + + @Test + public void testCheckNotNullWithOwner() { + E.checkNotNull(0, "test", "obj"); + E.checkNotNull(new Object(), "test", "obj"); + E.checkNotNull("1", "test", "obj"); + E.checkNotNull(ImmutableList.of(), "test", "obj"); + + Assert.assertThrows(NullPointerException.class, () -> { + E.checkNotNull(null, "test", "obj"); + }, e -> { + Assert.assertContains("The 'test' of 'obj' can't be null", + e.getMessage()); + }); + + Assert.assertThrows(NullPointerException.class, () -> { + E.checkNotNull(null, "test2", "obj2"); + }, e -> { + Assert.assertContains("The 'test2' of 'obj2' can't be null", + e.getMessage()); + }); + } + + @Test + public void testCheckNotEmpty() { + E.checkNotEmpty(ImmutableList.of(0), "test"); + E.checkNotEmpty(ImmutableList.of(""), "test"); + E.checkNotEmpty(ImmutableList.of(1, 2), "test"); + E.checkNotEmpty(ImmutableSet.of(0), "test"); + E.checkNotEmpty(ImmutableSet.of(""), "test"); + E.checkNotEmpty(ImmutableSet.of("1", "2"), "test"); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + E.checkNotEmpty(ImmutableList.of(), "test"); + }, e -> { + Assert.assertContains("The 'test' can't be empty", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + E.checkNotEmpty(ImmutableSet.of(), "test2"); + }, e -> { + Assert.assertContains("The 'test2' can't be empty", e.getMessage()); + }); + } + + @Test + public void testCheckNotEmptyWithOwner() { + E.checkNotEmpty(ImmutableList.of(0), "test", "obj"); + E.checkNotEmpty(ImmutableList.of(""), "test", "obj"); + E.checkNotEmpty(ImmutableList.of(1, 2), "test", "obj"); + E.checkNotEmpty(ImmutableSet.of(0), "test", "obj"); + E.checkNotEmpty(ImmutableSet.of(""), "test", "obj"); + E.checkNotEmpty(ImmutableSet.of("1", "2"), "test", "obj"); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + E.checkNotEmpty(ImmutableList.of(), "test", "obj"); + }, e -> { + Assert.assertContains("The 'test' of 'obj' can't be empty", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + E.checkNotEmpty(ImmutableSet.of(), "test2", "obj2"); + }, e -> { + Assert.assertContains("The 'test2' of 'obj2' can't be empty", + e.getMessage()); + }); + } + + @Test + public void testCheckArgument() { + E.checkArgument(true, "test"); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + E.checkArgument(false, "Invalid parameter %s", 123); + }, e -> { + Assert.assertContains("Invalid parameter 123", e.getMessage()); + }); + } + + @Test + public void testCheckArgumentNotNull() { + E.checkArgumentNotNull("", "test"); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + E.checkArgumentNotNull(null, "Invalid parameter %s", "null"); + }, e -> { + Assert.assertContains("Invalid parameter null", e.getMessage()); + }); + } + + @Test + public void testCheckState() { + E.checkState(true, "test"); + + Assert.assertThrows(IllegalStateException.class, () -> { + E.checkState(false, "Invalid state '%s'", "FAIL"); + }, e -> { + Assert.assertContains("Invalid state 'FAIL'", e.getMessage()); + }); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/HashUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/HashUtilTest.java new file mode 100644 index 0000000000..3efde1b55d --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/HashUtilTest.java @@ -0,0 +1,120 @@ +/* + * 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.unit.util; + +import org.junit.Test; + +import org.apache.hugegraph.util.Bytes; +import org.apache.hugegraph.util.HashUtil; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; + +public class HashUtilTest extends BaseUnitTest { + + @Test + public void testHash() { + // hash 32 bits (4 bytes) + + String h = HashUtil.hash(""); + Assert.assertEquals(8, h.length()); + Assert.assertEquals("00000000", h); + + h = HashUtil.hash("q"); + Assert.assertEquals(8, h.length()); + Assert.assertEquals("e80982ff", h); + + h = HashUtil.hash("qq"); + Assert.assertEquals(8, h.length()); + Assert.assertEquals("252ef918", h); + + h = HashUtil.hash("qwertyuiop[]asdfghjkl;'zxcvbnm,./"); + Assert.assertEquals(8, h.length()); + Assert.assertEquals("fcc1f9fa", h); + } + + @Test + public void testHashWithBytes() { + // hash 32 bits (4 bytes) + + byte[] h = HashUtil.hash(b("")); + Assert.assertEquals(4, h.length); + Assert.assertEquals("00000000", hex(h)); + + h = HashUtil.hash(b("q")); + Assert.assertEquals(4, h.length); + Assert.assertEquals("e80982ff", hex(h)); + + h = HashUtil.hash(b("qq")); + Assert.assertEquals(4, h.length); + Assert.assertEquals("252ef918", hex(h)); + + h = HashUtil.hash(b("qwertyuiop[]asdfghjkl;'zxcvbnm,./")); + Assert.assertEquals(4, h.length); + Assert.assertEquals("fcc1f9fa", hex(h)); + } + + @Test + public void testHash128() { + // hash 128 bits (16 bytes) + + String h = HashUtil.hash128(""); + Assert.assertEquals(32, h.length()); + Assert.assertEquals("00000000000000000000000000000000", h); + + h = HashUtil.hash128("q"); + Assert.assertEquals(32, h.length()); + Assert.assertEquals("b1aba139b20c3ebcf667a14f41c7d17c", h); + + h = HashUtil.hash128("qq"); + Assert.assertEquals(32, h.length()); + Assert.assertEquals("2dbabe8ac8d8ce9eedc4b97add0f7c7c", h); + + h = HashUtil.hash128("qwertyuiop[]asdfghjkl;'zxcvbnm,./"); + Assert.assertEquals(32, h.length()); + Assert.assertEquals("49780e7800e613230520ed7b1116fef5", h); + } + + @Test + public void testHash128WithBytes() { + // hash 128 bits (16 bytes) + + byte[] h = HashUtil.hash128(b("")); + Assert.assertEquals(16, h.length); + Assert.assertEquals("00000000000000000000000000000000", hex(h)); + + h = HashUtil.hash128(b("q")); + Assert.assertEquals(16, h.length); + Assert.assertEquals("b1aba139b20c3ebcf667a14f41c7d17c", hex(h)); + + h = HashUtil.hash128(b("qq")); + Assert.assertEquals(16, h.length); + Assert.assertEquals("2dbabe8ac8d8ce9eedc4b97add0f7c7c", hex(h)); + + h = HashUtil.hash128(b("qwertyuiop[]asdfghjkl;'zxcvbnm,./")); + Assert.assertEquals(16, h.length); + Assert.assertEquals("49780e7800e613230520ed7b1116fef5", hex(h)); + } + + private static byte[] b(String string) { + return string.getBytes(); + } + + private static String hex(byte[] bytes) { + return Bytes.toHex(bytes); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/InsertionOrderUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/InsertionOrderUtilTest.java new file mode 100644 index 0000000000..b2776a7d7f --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/InsertionOrderUtilTest.java @@ -0,0 +1,173 @@ +/* + * 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.unit.util; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Test; + +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.util.InsertionOrderUtil; +import org.apache.hugegraph.testutil.Assert; +import com.google.common.collect.ImmutableList; + +public class InsertionOrderUtilTest extends BaseUnitTest { + + @Test + public void testSet() { + Set set = InsertionOrderUtil.newSet(); + set.add(4); + set.add(2); + set.add(5); + set.add(1); + set.add(3); + + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(set)); + } + + @Test + public void testSetWithInitialCapacity() { + Set set = InsertionOrderUtil.newSet(3); + set.add(4); + set.add(2); + set.add(5); + set.add(1); + set.add(3); + + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(set)); + } + + @Test + public void testSetCopy() { + Set set = InsertionOrderUtil.newSet(); + set.add(4); + set.add(2); + set.add(5); + set.add(1); + set.add(3); + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(set)); + + Set set2 = InsertionOrderUtil.newSet(set); + set2.add(6); + set2.add(1); + + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3, 6), + ImmutableList.copyOf(set2)); + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(set)); + } + + @Test + public void testList() { + List list = InsertionOrderUtil.newList(); + list.add(4); + list.add(2); + list.add(5); + list.add(1); + list.add(3); + + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(list)); + } + + @Test + public void testListWithInitialCapacity() { + List list = InsertionOrderUtil.newList(3); + list.add(4); + list.add(2); + list.add(5); + list.add(1); + list.add(3); + + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(list)); + } + + @Test + public void testListCopy() { + List list = InsertionOrderUtil.newList(); + list.add(4); + list.add(2); + list.add(5); + list.add(1); + list.add(3); + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(list)); + + List list2 = InsertionOrderUtil.newList(list); + list2.add(6); + list2.add(1); + + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3, 6, 1), + ImmutableList.copyOf(list2)); + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(list)); + } + + @Test + public void testMap() { + Map map = InsertionOrderUtil.newMap(); + map.put(4, 4); + map.put(2, 2); + map.put(5, 5); + map.put(1, 1); + map.put(3, 3); + + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(map.keySet())); + } + + @Test + public void testMapWithInitialCapacity() { + Map map = InsertionOrderUtil.newMap(3); + map.put(4, 4); + map.put(2, 2); + map.put(5, 5); + map.put(1, 1); + map.put(3, 3); + + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(map.keySet())); + } + + @Test + public void testMapCopy() { + Map map = InsertionOrderUtil.newMap(3); + map.put(4, 4); + map.put(2, 2); + map.put(5, 5); + map.put(1, 1); + map.put(3, 3); + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(map.keySet())); + + Map map2 = InsertionOrderUtil.newMap(map); + map2.put(6, 6); + map2.put(1, 7); + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3, 6), + ImmutableList.copyOf(map2.keySet())); + + Assert.assertEquals(ImmutableList.of(4, 2, 5, 1, 3), + ImmutableList.copyOf(map.keySet())); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/LogTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/LogTest.java new file mode 100644 index 0000000000..9ab55c8fd3 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/LogTest.java @@ -0,0 +1,42 @@ +/* + * 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.unit.util; + +import org.junit.Test; +import org.slf4j.Logger; + +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.util.Log; +import org.apache.hugegraph.testutil.Assert; + +public class LogTest extends BaseUnitTest { + + @Test + public void testLog() { + Logger log1 = Log.logger(LogTest.class); + Logger log2 = Log.logger("org.apache.hugegraph.unit.util.LogTest"); + Logger log3 = Log.logger("test"); + + Assert.assertEquals(log1, log2); + Assert.assertNotEquals(log1, log3); + + log1.info("Info: testLog({})", LogTest.class); + log2.info("Info: testLog({})", "org.apache.hugegraph.unit.util.LogTest"); + log3.info("Info: testLog({})", "test"); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/LongEncodingTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/LongEncodingTest.java new file mode 100644 index 0000000000..8e822058c8 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/LongEncodingTest.java @@ -0,0 +1,684 @@ +/* + * 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.unit.util; + +import java.math.BigDecimal; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Random; +import java.util.TimeZone; + +import org.junit.Test; + +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.util.Bytes; +import org.apache.hugegraph.util.LongEncoding; +import org.apache.hugegraph.util.NumericUtil; +import org.apache.hugegraph.testutil.Assert; + +public class LongEncodingTest extends BaseUnitTest { + + @Test + public void testValidB64Char() { + Assert.assertTrue(LongEncoding.validB64Char('0')); + Assert.assertTrue(LongEncoding.validB64Char('1')); + Assert.assertTrue(LongEncoding.validB64Char('9')); + Assert.assertTrue(LongEncoding.validB64Char('A')); + Assert.assertTrue(LongEncoding.validB64Char('Z')); + Assert.assertTrue(LongEncoding.validB64Char('_')); + Assert.assertTrue(LongEncoding.validB64Char('a')); + Assert.assertTrue(LongEncoding.validB64Char('z')); + Assert.assertTrue(LongEncoding.validB64Char('~')); + + Assert.assertFalse(LongEncoding.validB64Char('`')); + Assert.assertFalse(LongEncoding.validB64Char('!')); + Assert.assertFalse(LongEncoding.validB64Char('@')); + Assert.assertFalse(LongEncoding.validB64Char('#')); + Assert.assertFalse(LongEncoding.validB64Char('$')); + Assert.assertFalse(LongEncoding.validB64Char('%')); + Assert.assertFalse(LongEncoding.validB64Char('^')); + Assert.assertFalse(LongEncoding.validB64Char('&')); + Assert.assertFalse(LongEncoding.validB64Char('*')); + Assert.assertFalse(LongEncoding.validB64Char('(')); + Assert.assertFalse(LongEncoding.validB64Char(')')); + Assert.assertFalse(LongEncoding.validB64Char('-')); + Assert.assertFalse(LongEncoding.validB64Char('+')); + Assert.assertFalse(LongEncoding.validB64Char('=')); + Assert.assertFalse(LongEncoding.validB64Char('[')); + Assert.assertFalse(LongEncoding.validB64Char(']')); + Assert.assertFalse(LongEncoding.validB64Char('{')); + Assert.assertFalse(LongEncoding.validB64Char('}')); + Assert.assertFalse(LongEncoding.validB64Char('|')); + Assert.assertFalse(LongEncoding.validB64Char('\\')); + Assert.assertFalse(LongEncoding.validB64Char(';')); + Assert.assertFalse(LongEncoding.validB64Char(':')); + Assert.assertFalse(LongEncoding.validB64Char('\'')); + Assert.assertFalse(LongEncoding.validB64Char('\"')); + Assert.assertFalse(LongEncoding.validB64Char('<')); + Assert.assertFalse(LongEncoding.validB64Char(',')); + Assert.assertFalse(LongEncoding.validB64Char('>')); + Assert.assertFalse(LongEncoding.validB64Char('.')); + Assert.assertFalse(LongEncoding.validB64Char('?')); + Assert.assertFalse(LongEncoding.validB64Char('/')); + Assert.assertFalse(LongEncoding.validB64Char('\t')); + Assert.assertFalse(LongEncoding.validB64Char('\b')); + } + + @Test + public void testEncode() { + String val0 = LongEncoding.encodeB64(0); + Assert.assertEquals("0", val0); + + String val1 = LongEncoding.encodeB64(1); + Assert.assertEquals("1", val1); + + String val9 = LongEncoding.encodeB64(9); + Assert.assertEquals("9", val9); + + String val10 = LongEncoding.encodeB64(10); + Assert.assertEquals("A", val10); + + String val35 = LongEncoding.encodeB64(35); + Assert.assertEquals("Z", val35); + + String val36 = LongEncoding.encodeB64(36); + Assert.assertEquals("_", val36); + + String val37 = LongEncoding.encodeB64(37); + Assert.assertEquals("a", val37); + + String val62 = LongEncoding.encodeB64(62); + Assert.assertEquals("z", val62); + + String val63 = LongEncoding.encodeB64(63); + Assert.assertEquals("~", val63); + } + + @Test + public void testEncodeWithMultiString() { + Assert.assertEquals("0", LongEncoding.encode(0L, "0123456789")); + Assert.assertEquals("1", LongEncoding.encode(1L, "0123456789")); + Assert.assertEquals("123", LongEncoding.encode(123L, "0123456789")); + Assert.assertEquals("13579", LongEncoding.encode(13579L, "0123456789")); + Assert.assertEquals("24680", LongEncoding.encode(24680L, "0123456789")); + + String val64 = LongEncoding.encodeB64(64); + Assert.assertEquals("10", val64); + + String val65 = LongEncoding.encodeB64(65); + Assert.assertEquals("11", val65); + + String val99 = LongEncoding.encodeB64(99); + Assert.assertEquals("1Z", val99); + + String val100 = LongEncoding.encodeB64(100); + Assert.assertEquals("1_", val100); + + String val126 = LongEncoding.encodeB64(126); + Assert.assertEquals("1z", val126); + + String val127 = LongEncoding.encodeB64(127); + Assert.assertEquals("1~", val127); + + String val128 = LongEncoding.encodeB64(128); + Assert.assertEquals("20", val128); + + String val200 = LongEncoding.encodeB64(200); + Assert.assertEquals("38", val200); + + String val1000 = LongEncoding.encodeB64(1000); + Assert.assertEquals("Fd", val1000); + + String val1234 = LongEncoding.encodeB64(1234); + Assert.assertEquals("JI", val1234); + + String val10000 = LongEncoding.encodeB64(10000); + Assert.assertEquals("2SG", val10000); + + String val12345 = LongEncoding.encodeB64(12345); + Assert.assertEquals("30u", val12345); + + String val22345 = LongEncoding.encodeB64(22345); + Assert.assertEquals("5T9", val22345); + + String val92345 = LongEncoding.encodeB64(92345); + Assert.assertEquals("MYu", val92345); + + String val12345678 = LongEncoding.encodeB64(12345678); + Assert.assertEquals("k65E", val12345678); + + String val112345678 = LongEncoding.encodeB64(112345678); + Assert.assertEquals("6h_9E", val112345678); + + String valIntMax = LongEncoding.encodeB64(Integer.MAX_VALUE); + Assert.assertEquals("1~~~~~", valIntMax); + + String valLongMax = LongEncoding.encodeB64(Long.MAX_VALUE); + Assert.assertEquals("7~~~~~~~~~~", valLongMax); + } + + @Test + public void testEncodeWithError() { + Assert.assertThrows(IllegalArgumentException.class, () -> { + LongEncoding.encode(1, ""); + }, e -> { + Assert.assertEquals("The symbols parameter can't be empty", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + LongEncoding.encode(-1, ""); + }, e -> { + Assert.assertContains("Expected non-negative number", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + LongEncoding.encodeB64(-1); + }, e -> { + Assert.assertContains("Expected non-negative number", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + LongEncoding.encodeB64(Long.MIN_VALUE); + }, e -> { + Assert.assertContains("Expected non-negative number", + e.getMessage()); + }); + } + + @Test + public void testDecode() { + long valEmpty = LongEncoding.decodeB64(""); + Assert.assertEquals(0, valEmpty); + + long val0 = LongEncoding.decodeB64("0"); + Assert.assertEquals(0, val0); + + long val1 = LongEncoding.decodeB64("1"); + Assert.assertEquals(1, val1); + + long val9 = LongEncoding.decodeB64("9"); + Assert.assertEquals(9, val9); + + long val10 = LongEncoding.decodeB64("A"); + Assert.assertEquals(10, val10); + + long val35 = LongEncoding.decodeB64("Z"); + Assert.assertEquals(35, val35); + + long val36 = LongEncoding.decodeB64("_"); + Assert.assertEquals(36, val36); + + long val37 = LongEncoding.decodeB64("a"); + Assert.assertEquals(37, val37); + + long val62 = LongEncoding.decodeB64("z"); + Assert.assertEquals(62, val62); + + long val63 = LongEncoding.decodeB64("~"); + Assert.assertEquals(63, val63); + } + + @Test + public void testDecodeWithMultiString() { + Assert.assertEquals(0L, LongEncoding.decode("0", "0123456789")); + Assert.assertEquals(1L, LongEncoding.decode("1", "0123456789")); + Assert.assertEquals(123L, LongEncoding.decode("123", "0123456789")); + Assert.assertEquals(13579L, LongEncoding.decode("13579", "0123456789")); + Assert.assertEquals(24680L, LongEncoding.decode("24680", "0123456789")); + + long val64 = LongEncoding.decodeB64("10"); + Assert.assertEquals(64, val64); + + long val65 = LongEncoding.decodeB64("11"); + Assert.assertEquals(65, val65); + + long val99 = LongEncoding.decodeB64("1Z"); + Assert.assertEquals(99, val99); + + long val100 = LongEncoding.decodeB64("1_"); + Assert.assertEquals(100, val100); + + long val126 = LongEncoding.decodeB64("1z"); + Assert.assertEquals(126, val126); + + long val127 = LongEncoding.decodeB64("1~"); + Assert.assertEquals(127, val127); + + long val128 = LongEncoding.decodeB64("20"); + Assert.assertEquals(128, val128); + + long val200 = LongEncoding.decodeB64("38"); + Assert.assertEquals(200, val200); + + long val1000 = LongEncoding.decodeB64("Fd"); + Assert.assertEquals(1000, val1000); + + long val1234 = LongEncoding.decodeB64("JI"); + Assert.assertEquals(1234, val1234); + + long val10000 = LongEncoding.decodeB64("2SG"); + Assert.assertEquals(10000, val10000); + + long val12345 = LongEncoding.decodeB64("30u"); + Assert.assertEquals(12345, val12345); + + long val22345 = LongEncoding.decodeB64("5T9"); + Assert.assertEquals(22345, val22345); + + long val92345 = LongEncoding.decodeB64("MYu"); + Assert.assertEquals(92345, val92345); + + long val12345678 = LongEncoding.decodeB64("k65E"); + Assert.assertEquals(12345678, val12345678); + + long val112345678 = LongEncoding.decodeB64("6h_9E"); + Assert.assertEquals(112345678, val112345678); + + long valIntMax = LongEncoding.decodeB64("1~~~~~"); + Assert.assertEquals(Integer.MAX_VALUE, valIntMax); + + long valLongMax = LongEncoding.decodeB64("7~~~~~~~~~~"); + Assert.assertEquals(Long.MAX_VALUE, valLongMax); + } + + @Test + public void testDecodeWithError() { + Assert.assertThrows(IllegalArgumentException.class, () -> { + LongEncoding.decode("1", ""); + }, e -> { + Assert.assertEquals("The symbols parameter can't be empty", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + LongEncoding.decode("1a", "0123456789"); + }, e -> { + Assert.assertEquals("Can't decode symbol 'a' in string '1a'", + e.getMessage()); + }); + } + + @Test + public void testEncodeSignedB64() { + String val1234 = LongEncoding.encodeSignedB64(1234); + Assert.assertEquals("JI", val1234); + + String val23 = LongEncoding.encodeSignedB64(23); + Assert.assertEquals("N", val23); + + String valIntMax = LongEncoding.encodeSignedB64(Integer.MAX_VALUE); + Assert.assertEquals("1~~~~~", valIntMax); + + String valLongMax = LongEncoding.encodeSignedB64(Long.MAX_VALUE); + Assert.assertEquals("7~~~~~~~~~~", valLongMax); + + String val0 = LongEncoding.encodeSignedB64(0); + Assert.assertEquals("0", val0); + + String valNeg1 = LongEncoding.encodeSignedB64(-1); + Assert.assertEquals("-1", valNeg1); + + String valIntMinP1 = LongEncoding.encodeSignedB64(Integer.MIN_VALUE + + 1L); + Assert.assertEquals("-1~~~~~", valIntMinP1); + + String valIntMin = LongEncoding.encodeSignedB64(Integer.MIN_VALUE); + Assert.assertEquals("-200000", valIntMin); + + String valLongMinPlus1 = LongEncoding.encodeSignedB64(Long.MIN_VALUE + + 1L); + Assert.assertEquals("-7~~~~~~~~~~", valLongMinPlus1); + + String valLongMin = LongEncoding.encodeSignedB64(Long.MIN_VALUE); + Assert.assertEquals("-80000000000", valLongMin); + } + + @Test + public void testDecodeSignedB64() { + long val1234 = LongEncoding.decodeSignedB64("JI"); + Assert.assertEquals(1234, val1234); + + long val23 = LongEncoding.decodeSignedB64("N"); + Assert.assertEquals(23, val23); + + long valIntMax = LongEncoding.decodeSignedB64("1~~~~~"); + Assert.assertEquals(Integer.MAX_VALUE, valIntMax); + + long valLongMax = LongEncoding.decodeSignedB64("7~~~~~~~~~~"); + Assert.assertEquals(Long.MAX_VALUE, valLongMax); + + long val0 = LongEncoding.decodeSignedB64("0"); + Assert.assertEquals(0, val0); + + long valn1 = LongEncoding.decodeSignedB64("-1"); + Assert.assertEquals(-1, valn1); + + long valIntMinPlus1 = LongEncoding.decodeSignedB64("-1~~~~~"); + Assert.assertEquals(Integer.MIN_VALUE + 1L, valIntMinPlus1); + + long valIntMin = LongEncoding.decodeSignedB64("-200000"); + Assert.assertEquals(Integer.MIN_VALUE, valIntMin); + + long valLongMinPlus1 = LongEncoding.decodeSignedB64("-7~~~~~~~~~~"); + Assert.assertEquals(Long.MIN_VALUE + 1L, valLongMinPlus1); + + long valLongMin = LongEncoding.decodeSignedB64("-80000000000"); + Assert.assertEquals(Long.MIN_VALUE, valLongMin); + } + + @Test + public void testDecodeSignedB64Overflow() { + long valOverflow = LongEncoding.decodeSignedB64("80000000000"); + Assert.assertEquals(Long.MIN_VALUE, valOverflow); + + long valOverflow2 = LongEncoding.decodeSignedB64("80000000001"); + Assert.assertEquals(Long.MIN_VALUE + 1L, valOverflow2); + + long valOverflow3 = LongEncoding.decodeSignedB64("800000000001"); + Assert.assertEquals(1L, valOverflow3); + + long valOverflow4 = LongEncoding.decodeSignedB64("80000000000JI"); + Assert.assertEquals(1234L, valOverflow4); + + long valOverflow5 = LongEncoding.decodeSignedB64("80000000000N"); + Assert.assertEquals(23L, valOverflow5); + + long valOverflow6 = LongEncoding.decodeSignedB64("80000000000" + + "7~~~~~~~~~~"); + Assert.assertEquals(Long.MAX_VALUE, valOverflow6); + } + + @Test + public void testEncodeSortable() { + String val1234 = LongEncoding.encodeSortable(1234); + Assert.assertEquals("2JI", val1234); + + String val23 = LongEncoding.encodeSortable(23); + Assert.assertEquals("1N", val23); + + String valIntMax = LongEncoding.encodeSortable(Integer.MAX_VALUE); + Assert.assertEquals("61~~~~~", valIntMax); + + String valLongMax = LongEncoding.encodeSortable(Long.MAX_VALUE); + Assert.assertEquals("B7~~~~~~~~~~", valLongMax); + + String val0 = LongEncoding.encodeSortable(0); + Assert.assertEquals("10", val0); + + String valNeg1 = LongEncoding.encodeSortable(-1); + Assert.assertEquals("0B7~~~~~~~~~~", valNeg1); + + String valIntMin = LongEncoding.encodeSortable(Integer.MIN_VALUE); + Assert.assertEquals("0B7~~~~z00000", valIntMin); + + String valLongMin = LongEncoding.encodeSortable(Long.MIN_VALUE); + Assert.assertEquals("010", valLongMin); + } + + @Test + public void testDecodeSortable() { + long val1234 = LongEncoding.decodeSortable("2JI"); + Assert.assertEquals(1234, val1234); + + long val23 = LongEncoding.decodeSortable("1N"); + Assert.assertEquals(23, val23); + + long valIntMax = LongEncoding.decodeSortable("61~~~~~"); + Assert.assertEquals(Integer.MAX_VALUE, valIntMax); + + long valLongMax = LongEncoding.decodeSortable("B7~~~~~~~~~~"); + Assert.assertEquals(Long.MAX_VALUE, valLongMax); + + long val0 = LongEncoding.decodeSortable("10"); + Assert.assertEquals(0, val0); + + long valn1 = LongEncoding.decodeSortable("0B7~~~~~~~~~~"); + Assert.assertEquals(-1, valn1); + + long valIntMin = LongEncoding.decodeSortable("0B7~~~~z00000"); + Assert.assertEquals(Integer.MIN_VALUE, valIntMin); + + long valLongMin = LongEncoding.decodeSortable("010"); + Assert.assertEquals(Long.MIN_VALUE, valLongMin); + } + + @Test + public void testDecodeIllegalSortable() { + // Length is 1, actual length is 0 + Assert.assertThrows(IllegalArgumentException.class, () -> { + LongEncoding.decodeSortable("1"); + }); + + // Length is 1, actual length is 2 + Assert.assertThrows(IllegalArgumentException.class, () -> { + LongEncoding.decodeSortable("123"); + }); + + // Length is 1, actual length is 0 + Assert.assertThrows(IllegalArgumentException.class, () -> { + LongEncoding.decodeSortable("01"); + }); + + // Length is 1, actual length is 2 + Assert.assertThrows(IllegalArgumentException.class, () -> { + LongEncoding.decodeSortable("0123"); + }); + } + + @Test + public void testEncodeNumber() throws ParseException { + String l1234 = LongEncoding.encodeNumber(1234); + Assert.assertEquals("2JI", l1234); + + String d1234 = LongEncoding.encodeNumber(1.234); + Assert.assertEquals("B3~okcR8i3aO", d1234); + + String d21 = LongEncoding.encodeNumber(2.1); + Assert.assertEquals("B400oCoCoCoD", d21); + + String dpi = LongEncoding.encodeNumber(3.1415926); + Assert.assertEquals("B4098ViD4iXA", dpi); + + String fpi = LongEncoding.encodeNumber(3.1415926f); + Assert.assertEquals("610IG~Q", fpi); + + String fn1 = LongEncoding.encodeNumber(-1.0f); + Assert.assertEquals("0B7~~~~~0V~~~", fn1); + + String bMax = LongEncoding.encodeNumber(Byte.MAX_VALUE); + Assert.assertEquals("21~", bMax); + + String bMin = LongEncoding.encodeNumber(Byte.MIN_VALUE); + Assert.assertEquals("0B7~~~~~~~~z0", bMin); + + String sMax = LongEncoding.encodeNumber(Short.MAX_VALUE); + Assert.assertEquals("37~~", sMax); + + String sMin = LongEncoding.encodeNumber(Short.MIN_VALUE); + Assert.assertEquals("0B7~~~~~~~t00", sMin); + + String iMax = LongEncoding.encodeNumber(Integer.MAX_VALUE); + Assert.assertEquals("61~~~~~", iMax); + + String iMin = LongEncoding.encodeNumber(Integer.MIN_VALUE); + Assert.assertEquals("0B7~~~~z00000", iMin); + + String lMax = LongEncoding.encodeNumber(Long.MAX_VALUE); + Assert.assertEquals("B7~~~~~~~~~~", lMax); + + String lMin = LongEncoding.encodeNumber(Long.MIN_VALUE); + Assert.assertEquals("010", lMin); + + String fMax = LongEncoding.encodeNumber(Float.MAX_VALUE); + Assert.assertEquals("61~V~~~", fMax); + + String fMin = LongEncoding.encodeNumber(Float.MIN_VALUE); + Assert.assertEquals("11", fMin); + + String dMax = LongEncoding.encodeNumber(Double.MAX_VALUE); + Assert.assertEquals("B7~k~~~~~~~~", dMax); + + String dMin = LongEncoding.encodeNumber(Double.MIN_VALUE); + Assert.assertEquals("11", dMin); + + String bdLong = LongEncoding.encodeNumber(new BigDecimal("1234")); + Assert.assertEquals("2JI", bdLong); + + String bdFLong = LongEncoding.encodeNumber(new BigDecimal("1234.00")); + Assert.assertEquals("2JI", bdFLong); + + String bdDouble = LongEncoding.encodeNumber(new BigDecimal("1.234")); + Assert.assertEquals("B3~okcR8i3aO", bdDouble); + + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); + Date time = dateFormat.parse("2018-12-18"); + String date = LongEncoding.encodeNumber(time); + Assert.assertEquals("7MUxuK00", date); + } + + @Test + public void testDecodeNumber() { + Number l1234 = LongEncoding.decodeNumber("2JI", Long.class); + Assert.assertEquals(1234L, l1234); + + Number d1234 = LongEncoding.decodeNumber("B3~okcR8i3aO", Double.class); + Assert.assertEquals(1.234, d1234); + + Number d21 = LongEncoding.decodeNumber("B400oCoCoCoD", Double.class); + Assert.assertEquals(2.1, d21); + + Number dpi = LongEncoding.decodeNumber("B4098ViD4iXA", Double.class); + Assert.assertEquals(3.1415926, dpi); + + Number fpi = LongEncoding.decodeNumber("610IG~Q", Float.class); + Assert.assertEquals(3.1415926f, fpi); + + Number fn1 = LongEncoding.decodeNumber("0B7~~~~~0V~~~", Float.class); + Assert.assertEquals(-1.0f, fn1); + + Number bMax = LongEncoding.decodeNumber("21~", Byte.class); + Assert.assertEquals(Byte.MAX_VALUE, bMax); + + Number bMin = LongEncoding.decodeNumber("0B7~~~~~~~~z0", Byte.class); + Assert.assertEquals(Byte.MIN_VALUE, bMin); + + Number sMax = LongEncoding.decodeNumber("37~~", Short.class); + Assert.assertEquals(Short.MAX_VALUE, sMax); + + Number sMin = LongEncoding.decodeNumber("0B7~~~~~~~t00", Short.class); + Assert.assertEquals(Short.MIN_VALUE, sMin); + + Number iMax = LongEncoding.decodeNumber("61~~~~~", Integer.class); + Assert.assertEquals(Integer.MAX_VALUE, iMax); + + Number iMin = LongEncoding.decodeNumber("0B7~~~~z00000", Integer.class); + Assert.assertEquals(Integer.MIN_VALUE, iMin); + + Number lMax = LongEncoding.decodeNumber("B7~~~~~~~~~~", Long.class); + Assert.assertEquals(Long.MAX_VALUE, lMax); + + Number lMin = LongEncoding.decodeNumber("010", Long.class); + Assert.assertEquals(Long.MIN_VALUE, lMin); + + Number fMax = LongEncoding.decodeNumber("61~V~~~", Float.class); + Assert.assertEquals(Float.MAX_VALUE, fMax); + + Number fMin = LongEncoding.decodeNumber("11", Float.class); + Assert.assertEquals(Float.MIN_VALUE, fMin); + + Number dMax = LongEncoding.decodeNumber("B7~k~~~~~~~~", Double.class); + Assert.assertEquals(Double.MAX_VALUE, dMax); + + Number dMin = LongEncoding.decodeNumber("11", Double.class); + Assert.assertEquals(Double.MIN_VALUE, dMin); + } + + @Test + public void testEncodeSortableThenCompare() { + int count = 100000; + Random random1 = new Random(); + Random random2 = new Random(); + for (int i = 0; i < count; i++) { + long num1 = random1.nextLong(); + long num2 = random2.nextLong(); + + String encoded1 = LongEncoding.encodeSortable(num1); + String encoded2 = LongEncoding.encodeSortable(num2); + int cmp = Bytes.compare(encoded1.getBytes(), encoded2.getBytes()); + + if (num1 == num2) { + Assert.assertEquals(0, cmp); + } else if (num1 > num2) { + Assert.assertTrue(cmp > 0); + } else { + assert num1 < num2; + Assert.assertTrue(cmp < 0); + } + } + } + + @Test + public void testEncodeNumberThenCompare() { + int count = 100000; + Random random1 = new Random(); + Random random2 = new Random(); + + for (int i = 0; i < count; i++) { + compareEncodedNumber(random1.nextInt(), random2.nextInt()); + } + for (int i = 0; i < count; i++) { + compareEncodedNumber(random1.nextLong(), random2.nextLong()); + } + + for (int i = 0; i < count; i++) { + compareEncodedNumber(random1.nextInt(), random2.nextLong()); + } + for (int i = 0; i < count; i++) { + compareEncodedNumber(random1.nextLong(), random2.nextInt()); + } + + for (int i = 0; i < count; i++) { + compareEncodedNumber(random1.nextFloat(), random2.nextFloat()); + } + for (int i = 0; i < count; i++) { + compareEncodedNumber(random1.nextDouble(), random2.nextDouble()); + } + } + + private static void compareEncodedNumber(Number num1, Number num2) { + int cmpExpected = NumericUtil.compareNumber(num1, num2); + + String encoded1 = LongEncoding.encodeNumber(num1); + String encoded2 = LongEncoding.encodeNumber(num2); + int cmp = Bytes.compare(encoded1.getBytes(), encoded2.getBytes()); + + if (cmpExpected == 0) { + Assert.assertEquals(0, cmp); + } else if (cmpExpected > 0) { + Assert.assertTrue(cmp > 0); + } else { + assert cmpExpected < 0; + Assert.assertTrue(cmp < 0); + } + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/NumericUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/NumericUtilTest.java new file mode 100644 index 0000000000..fc1f0d6149 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/NumericUtilTest.java @@ -0,0 +1,475 @@ +/* + * 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.unit.util; + +import java.math.BigDecimal; +import java.util.Date; + +import org.junit.Test; + +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.util.Bytes; +import org.apache.hugegraph.util.NumericUtil; +import org.apache.hugegraph.testutil.Assert; + +public class NumericUtilTest extends BaseUnitTest { + + @Test + public void testNumberToSortableBytes() { + // byte + byte[] bytes = NumericUtil.numberToSortableBytes((byte) 0x33); + assertEquals(new byte[]{(byte) 0xb3}, bytes); + + bytes = NumericUtil.numberToSortableBytes(Byte.MIN_VALUE); + assertEquals(new byte[]{0x00}, bytes); + + bytes = NumericUtil.numberToSortableBytes(Byte.MAX_VALUE); + assertEquals(new byte[]{(byte) 0xff}, bytes); + + bytes = NumericUtil.numberToSortableBytes((byte) -1); + assertEquals(new byte[]{(byte) 0x7f}, bytes); + + bytes = NumericUtil.numberToSortableBytes((byte) 0); + assertEquals(new byte[]{(byte) 0x80}, bytes); + + // short + bytes = NumericUtil.numberToSortableBytes((short) 0x11223344); + assertEquals(new byte[]{(byte) 0x80, 0x00, 0x33, 0x44}, bytes); + + // int + bytes = NumericUtil.numberToSortableBytes(0x11223344); + assertEquals(new byte[]{(byte) 0x91, 0x22, 0x33, 0x44}, bytes); + + // long + bytes = NumericUtil.numberToSortableBytes(0x1122334455L); + assertEquals(new byte[]{(byte) 0x80, 0, 0, 0x11, + 0x22, 0x33, 0x44, 0x55}, bytes); + + // float + bytes = NumericUtil.numberToSortableBytes(3.14f); + assertEquals(new byte[]{(byte) 0xc0, 0x48, (byte) 0xf5, (byte) 0xc3}, + bytes); + + // double + bytes = NumericUtil.numberToSortableBytes(3.1415926d); + assertEquals(new byte[]{(byte) 0xc0, 0x09, 0x21, (byte) 0xfb, + 0x4d, 0x12, (byte) 0xd8, 0x4a}, bytes); + + // BigDecimal + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.numberToSortableBytes(new BigDecimal(123)); + }); + } + + @Test + public void testSortableBytesToNumber() { + // byte + Number value = NumericUtil.sortableBytesToNumber(new byte[]{0x33}, + Byte.class); + Assert.assertEquals(value, (byte) 0xb3); + + value = NumericUtil.sortableBytesToNumber(new byte[]{(byte) 0x00}, + Byte.class); + Assert.assertEquals(value, Byte.MIN_VALUE); + + value = NumericUtil.sortableBytesToNumber(new byte[]{(byte) 0xff}, + Byte.class); + Assert.assertEquals(value, Byte.MAX_VALUE); + + value = NumericUtil.sortableBytesToNumber(new byte[]{(byte) 0x7f}, + Byte.class); + Assert.assertEquals(value, (byte) -1); + + value = NumericUtil.sortableBytesToNumber(new byte[]{(byte) 0x80}, + Byte.class); + Assert.assertEquals(value, (byte) 0); + + // short + value = NumericUtil.sortableBytesToNumber(new byte[]{0, 0, 0x33, 0x44}, + Short.class); + Assert.assertEquals((short) 0x3344, value); + + // int + value = NumericUtil.sortableBytesToNumber( + new byte[]{(byte) 0x91, 0x22, 0x33, 0x44}, Integer.class); + Assert.assertEquals(0x11223344, value); + + // long + value = NumericUtil.sortableBytesToNumber( + new byte[]{(byte) 0x80, 0, 0, 0x11, 0x22, 0x33, 0x44, 0x55}, + Long.class); + Assert.assertEquals(0x1122334455L, value); + + // float + value = NumericUtil.sortableBytesToNumber( + new byte[]{(byte) 0xc0, 0x48, (byte) 0xf5, (byte) 0xc3}, + Float.class); + Assert.assertEquals(3.14f, value); + + // double + value = NumericUtil.sortableBytesToNumber( + new byte[]{(byte) 0xc0, 0x09, 0x21, (byte) 0xfb, + 0x4d, 0x12, (byte) 0xd8, 0x4a}, + Double.class); + Assert.assertEquals(3.1415926d, value); + + // BigDecimal + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.sortableBytesToNumber(new byte[123], BigDecimal.class); + }); + } + + @Test + public void testIntToSortableBytesAndCompare() { + byte[] bytes1 = NumericUtil.numberToSortableBytes(123456); + byte[] bytes2 = NumericUtil.numberToSortableBytes(123456); + Assert.assertEquals(0, Bytes.compare(bytes1, bytes2)); + + bytes1 = NumericUtil.numberToSortableBytes(1); + bytes2 = NumericUtil.numberToSortableBytes(2); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(666); + bytes2 = NumericUtil.numberToSortableBytes(88); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(Integer.MAX_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(0); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(-123456); + bytes2 = NumericUtil.numberToSortableBytes(-123456); + Assert.assertEquals(0, Bytes.compare(bytes1, bytes2)); + + bytes1 = NumericUtil.numberToSortableBytes(-1); + bytes2 = NumericUtil.numberToSortableBytes(-2); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(-666); + bytes2 = NumericUtil.numberToSortableBytes(-88); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(Integer.MIN_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(-1); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(0); + bytes2 = NumericUtil.numberToSortableBytes(-1); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(0); + bytes2 = NumericUtil.numberToSortableBytes(Integer.MIN_VALUE); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(1); + bytes2 = NumericUtil.numberToSortableBytes(-1); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(Integer.MAX_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(-1); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + } + + @Test + public void testLongToSortableBytesAndCompare() { + byte[] bytes1 = NumericUtil.numberToSortableBytes(123456L); + byte[] bytes2 = NumericUtil.numberToSortableBytes(123456L); + Assert.assertEquals(0, Bytes.compare(bytes1, bytes2)); + + bytes1 = NumericUtil.numberToSortableBytes(1L); + bytes2 = NumericUtil.numberToSortableBytes(2L); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(666L); + bytes2 = NumericUtil.numberToSortableBytes(88L); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(Long.MAX_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(0L); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(-123456L); + bytes2 = NumericUtil.numberToSortableBytes(-123456L); + Assert.assertEquals(0, Bytes.compare(bytes1, bytes2)); + + bytes1 = NumericUtil.numberToSortableBytes(-1L); + bytes2 = NumericUtil.numberToSortableBytes(-2L); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(-666L); + bytes2 = NumericUtil.numberToSortableBytes(-88L); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(Long.MIN_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(-1L); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(0L); + bytes2 = NumericUtil.numberToSortableBytes(-1L); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(0L); + bytes2 = NumericUtil.numberToSortableBytes(Long.MIN_VALUE); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(1L); + bytes2 = NumericUtil.numberToSortableBytes(-1L); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(Long.MAX_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(-1L); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + } + + @Test + public void testFloatToSortableBytesAndCompare() { + byte[] bytes1 = NumericUtil.numberToSortableBytes(123456F); + byte[] bytes2 = NumericUtil.numberToSortableBytes(123456F); + Assert.assertEquals(0, Bytes.compare(bytes1, bytes2)); + + bytes1 = NumericUtil.numberToSortableBytes(1F); + bytes2 = NumericUtil.numberToSortableBytes(2F); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(666F); + bytes2 = NumericUtil.numberToSortableBytes(88F); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(Float.MAX_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(0F); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(-123456F); + bytes2 = NumericUtil.numberToSortableBytes(-123456F); + Assert.assertEquals(0, Bytes.compare(bytes1, bytes2)); + + bytes1 = NumericUtil.numberToSortableBytes(-1F); + bytes2 = NumericUtil.numberToSortableBytes(-2F); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(-666F); + bytes2 = NumericUtil.numberToSortableBytes(-88F); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(-Float.MAX_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(-1F); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(0F); + bytes2 = NumericUtil.numberToSortableBytes(-1F); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(0F); + bytes2 = NumericUtil.numberToSortableBytes(-Float.MAX_VALUE); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(1F); + bytes2 = NumericUtil.numberToSortableBytes(-1F); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(Float.MAX_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(-1F); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + } + + @Test + public void testDoubleToSortableBytesAndCompare() { + byte[] bytes1 = NumericUtil.numberToSortableBytes(123456D); + byte[] bytes2 = NumericUtil.numberToSortableBytes(123456D); + Assert.assertEquals(0, Bytes.compare(bytes1, bytes2)); + + bytes1 = NumericUtil.numberToSortableBytes(1D); + bytes2 = NumericUtil.numberToSortableBytes(2D); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(666D); + bytes2 = NumericUtil.numberToSortableBytes(88D); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(Double.MAX_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(0D); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(-123456D); + bytes2 = NumericUtil.numberToSortableBytes(-123456D); + Assert.assertEquals(0, Bytes.compare(bytes1, bytes2)); + + bytes1 = NumericUtil.numberToSortableBytes(-1D); + bytes2 = NumericUtil.numberToSortableBytes(-2D); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(-666D); + bytes2 = NumericUtil.numberToSortableBytes(-88D); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(-Double.MAX_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(-1D); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) < 0); + + bytes1 = NumericUtil.numberToSortableBytes(0D); + bytes2 = NumericUtil.numberToSortableBytes(-1D); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(0D); + bytes2 = NumericUtil.numberToSortableBytes(-Double.MAX_VALUE); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(1D); + bytes2 = NumericUtil.numberToSortableBytes(-1D); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + + bytes1 = NumericUtil.numberToSortableBytes(Double.MAX_VALUE); + bytes2 = NumericUtil.numberToSortableBytes(-1F); + Assert.assertTrue(Bytes.compare(bytes1, bytes2) > 0); + } + + @Test + public void testMinValueOf() { + Assert.assertEquals(Byte.MIN_VALUE, + NumericUtil.minValueOf(Byte.class)); + + Assert.assertEquals(Integer.MIN_VALUE, + NumericUtil.minValueOf(Short.class)); + Assert.assertEquals(Integer.MIN_VALUE, + NumericUtil.minValueOf(Integer.class)); + Assert.assertEquals(Integer.MIN_VALUE, + NumericUtil.minValueOf(Float.class)); + + Assert.assertEquals(Long.MIN_VALUE, + NumericUtil.minValueOf(Long.class)); + Assert.assertEquals(Long.MIN_VALUE, + NumericUtil.minValueOf(Double.class)); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.minValueOf(null); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.minValueOf(Character.class); + }); + } + + @Test + public void testMaxValueOf() { + Assert.assertEquals(Byte.MAX_VALUE, + NumericUtil.maxValueOf(Byte.class)); + + Assert.assertEquals(Integer.MAX_VALUE, + NumericUtil.maxValueOf(Short.class)); + Assert.assertEquals(Integer.MAX_VALUE, + NumericUtil.maxValueOf(Integer.class)); + Assert.assertEquals(Integer.MAX_VALUE, + NumericUtil.maxValueOf(Float.class)); + + Assert.assertEquals(Long.MAX_VALUE, + NumericUtil.maxValueOf(Long.class)); + Assert.assertEquals(Long.MAX_VALUE, + NumericUtil.maxValueOf(Double.class)); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.maxValueOf(null); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.maxValueOf(Character.class); + }); + } + + @Test + public void testIsNumber() { + Assert.assertTrue(NumericUtil.isNumber(byte.class)); + Assert.assertTrue(NumericUtil.isNumber(Byte.class)); + Assert.assertTrue(NumericUtil.isNumber(short.class)); + Assert.assertTrue(NumericUtil.isNumber(Short.class)); + Assert.assertTrue(NumericUtil.isNumber(int.class)); + Assert.assertTrue(NumericUtil.isNumber(Integer.class)); + Assert.assertTrue(NumericUtil.isNumber(long.class)); + Assert.assertTrue(NumericUtil.isNumber(Long.class)); + Assert.assertTrue(NumericUtil.isNumber(float.class)); + Assert.assertTrue(NumericUtil.isNumber(Float.class)); + Assert.assertTrue(NumericUtil.isNumber(double.class)); + Assert.assertTrue(NumericUtil.isNumber(Double.class)); + + Assert.assertFalse(NumericUtil.isNumber(char.class)); + Assert.assertFalse(NumericUtil.isNumber(Character.class)); + + Assert.assertTrue(NumericUtil.isNumber(1)); + Assert.assertTrue(NumericUtil.isNumber(1L)); + Assert.assertTrue(NumericUtil.isNumber(1.0f)); + Assert.assertTrue(NumericUtil.isNumber(1.0d)); + Assert.assertFalse(NumericUtil.isNumber('1')); + Assert.assertFalse(NumericUtil.isNumber((Object) null)); + } + + @Test + public void testConvertToNumber() { + Assert.assertEquals(1, NumericUtil.convertToNumber(1)); + Assert.assertEquals(1.2, NumericUtil.convertToNumber(1.2)); + + Assert.assertEquals(new BigDecimal("1.25"), + NumericUtil.convertToNumber("1.25")); + + Date date = new Date(); + Assert.assertEquals(date.getTime(), NumericUtil.convertToNumber(date)); + + Assert.assertNull(NumericUtil.convertToNumber(null)); + } + + @Test + public void testCompareNumber() { + Assert.assertEquals(0, NumericUtil.compareNumber(2, 2)); + Assert.assertEquals(1, NumericUtil.compareNumber(10, 2)); + Assert.assertEquals(-1, NumericUtil.compareNumber(1, 2)); + + Assert.assertEquals(-1, NumericUtil.compareNumber("1", 2)); + Assert.assertEquals(0, NumericUtil.compareNumber("2.0", 2)); + Assert.assertEquals(1, NumericUtil.compareNumber("2.00001", 2)); + Assert.assertEquals(1, NumericUtil.compareNumber("3.8", 2)); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.compareNumber(null, 1); + }, e -> { + Assert.assertContains("The first parameter can't be null", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.compareNumber(2, null); + }, e -> { + Assert.assertContains("The second parameter can't be null", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.compareNumber("2", null); + }, e -> { + Assert.assertContains("The second parameter can't be null", + e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.compareNumber("f", 2); + }, e -> { + Assert.assertContains("Can't compare between 'f' and '2'", + e.getMessage()); + }); + } + + private static void assertEquals(byte[] bytes1, byte[] bytes2) { + Assert.assertTrue(Bytes.toHex(bytes1) + " != " + Bytes.toHex(bytes2), + Bytes.equals(bytes1, bytes2)); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/OrderLimitMapTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/OrderLimitMapTest.java new file mode 100644 index 0000000000..de8375c102 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/OrderLimitMapTest.java @@ -0,0 +1,208 @@ +/* + * 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.unit.util; + +import java.util.Map; + +import org.junit.Test; + +import org.apache.hugegraph.util.OrderLimitMap; +import org.apache.hugegraph.testutil.Assert; +import com.google.common.collect.ImmutableList; + +public class OrderLimitMapTest { + + @Test + public void testInvalidCapacity() { + Assert.assertThrows(IllegalArgumentException.class, () -> { + new OrderLimitMap<>(-1); + }, e -> { + Assert.assertEquals("The capacity must be > 0", e.getMessage()); + }); + } + + @Test + public void testMap() { + OrderLimitMap map = new OrderLimitMap<>(5); + map.put(4, 0.4); + map.put(2, 0.2); + map.put(5, 0.5); + map.put(1, 0.2); + map.put(3, 0.3); + + Assert.assertEquals(5, map.size()); + + Assert.assertEquals(0.2, map.get(2), 1E-9); + Assert.assertEquals(0.4, map.get(4), 1E-9); + + Assert.assertTrue(map.containsKey(1)); + Assert.assertTrue(map.containsKey(3)); + Assert.assertFalse(map.containsKey(6)); + + Assert.assertNull(map.get(6)); + + Assert.assertEquals(0.5, map.getOrDefault(5, 0.0), 1E-9); + Assert.assertEquals(0.0, map.getOrDefault(7, 0.0), 1E-9); + } + + @Test + public void testOrder() { + OrderLimitMap map = new OrderLimitMap<>(5); + map.put(1, 0.1); + map.put(2, 0.2); + map.put(3, 0.3); + map.put(4, 0.4); + map.put(5, 0.5); + + Assert.assertEquals(5, map.size()); + Assert.assertEquals(ImmutableList.of(5, 4, 3, 2, 1), + ImmutableList.copyOf(map.keySet())); + } + + @Test + public void testOrderWithIncrOrder() { + OrderLimitMap map = new OrderLimitMap<>(5, true); + map.put(1, 0.5); + map.put(2, 0.4); + map.put(3, 0.3); + map.put(4, 0.2); + map.put(5, 0.1); + + Assert.assertEquals(5, map.size()); + Assert.assertEquals(ImmutableList.of(5, 4, 3, 2, 1), + ImmutableList.copyOf(map.keySet())); + } + + @Test + public void testOrderWithDupValue() { + OrderLimitMap map = new OrderLimitMap<>(5); + map.put(1, 0.1); + map.put(2, 0.2); + map.put(3, 0.3); + map.put(4, 0.2); + map.put(5, 0.3); + + Assert.assertEquals(5, map.size()); + Assert.assertEquals(ImmutableList.of(3, 5, 2, 4, 1), + ImmutableList.copyOf(map.keySet())); + } + + @Test + public void testOrderWithDupValueAndKeyIncrOrder() { + OrderLimitMap map = new OrderLimitMap<>(5); + map.put(4, 0.2); + map.put(2, 0.2); + map.put(1, 0.1); + map.put(5, 0.3); + map.put(3, 0.3); + + Assert.assertEquals(5, map.size()); + Assert.assertEquals(ImmutableList.of(3, 5, 2, 4, 1), + ImmutableList.copyOf(map.keySet())); + } + + @Test + public void testOrderWithDupKey() { + OrderLimitMap map = new OrderLimitMap<>(5); + map.put(1, 0.1); + map.put(2, 0.2); + map.put(3, 0.3); + map.put(2, 0.4); + map.put(3, 0.2); + + Assert.assertEquals(3, map.size()); + Assert.assertEquals(ImmutableList.of(2, 3, 1), + ImmutableList.copyOf(map.keySet())); + } + + @Test + public void testLimit() { + OrderLimitMap map = new OrderLimitMap<>(5); + map.put(1, 0.1); + map.put(2, 0.2); + map.put(3, 0.3); + map.put(4, 0.4); + map.put(5, 0.5); + + map.put(6, 0.6); + Assert.assertEquals(5, map.size()); + Assert.assertEquals(ImmutableList.of(6, 5, 4, 3, 2), + ImmutableList.copyOf(map.keySet())); + + map.put(7, 0.7); + Assert.assertEquals(5, map.size()); + Assert.assertEquals(ImmutableList.of(7, 6, 5, 4, 3), + ImmutableList.copyOf(map.keySet())); + } + + @Test + public void testLimitWithDupValue() { + OrderLimitMap map = new OrderLimitMap<>(5); + map.put(1, 0.1); + map.put(2, 0.2); + map.put(3, 0.3); + map.put(4, 0.4); + map.put(5, 0.5); + + map.put(6, 0.1); + Assert.assertEquals(5, map.size()); + Assert.assertEquals(ImmutableList.of(5, 4, 3, 2, 6), + ImmutableList.copyOf(map.keySet())); + + map.put(7, 0.3); + Assert.assertEquals(5, map.size()); + Assert.assertEquals(ImmutableList.of(5, 4, 3, 7, 2), + ImmutableList.copyOf(map.keySet())); + + map.put(8, 0.5); + Assert.assertEquals(5, map.size()); + Assert.assertEquals(ImmutableList.of(5, 8, 4, 3, 7), + ImmutableList.copyOf(map.keySet())); + + map.put(0, 0.5); + Assert.assertEquals(5, map.size()); + Assert.assertEquals(ImmutableList.of(0, 5, 8, 4, 3), + ImmutableList.copyOf(map.keySet())); + } + + @Test + public void testTopN() { + OrderLimitMap map = new OrderLimitMap<>(5); + map.put(1, 0.1); + map.put(2, 0.2); + map.put(3, 0.3); + map.put(4, 0.4); + map.put(5, 0.5); + + Map top = map.topN(1); + Assert.assertEquals(ImmutableList.of(5), + ImmutableList.copyOf(top.keySet())); + + top = map.topN(3); + Assert.assertEquals(ImmutableList.of(5, 4, 3), + ImmutableList.copyOf(top.keySet())); + + top = map.topN(5); + Assert.assertEquals(ImmutableList.of(5, 4, 3, 2, 1), + ImmutableList.copyOf(top.keySet())); + + top = map.topN(6); + Assert.assertEquals(ImmutableList.of(5, 4, 3, 2, 1), + ImmutableList.copyOf(top.keySet())); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/ReflectionUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/ReflectionUtilTest.java new file mode 100644 index 0000000000..f511ddfc7d --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/ReflectionUtilTest.java @@ -0,0 +1,161 @@ +/* + * 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.unit.util; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Comparator; +import java.util.List; + +import org.apache.commons.collections.IteratorUtils; +import org.apache.hugegraph.perf.PerfUtil; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.apache.hugegraph.unit.perf.testclass.TestClass; +import org.apache.hugegraph.unit.perf.testclass.TestClass.Bar; +import org.apache.hugegraph.unit.perf.testclass.TestClass.Base; +import org.apache.hugegraph.unit.perf.testclass.TestClass.Foo; +import org.apache.hugegraph.unit.perf.testclass.TestClass.ManuallyProfile; +import org.apache.hugegraph.unit.perf.testclass.TestClass.Sub; +import org.apache.hugegraph.util.ReflectionUtil; +import org.junit.Test; + +import com.google.common.reflect.ClassPath.ClassInfo; + +import javassist.NotFoundException; + +public class ReflectionUtilTest extends BaseUnitTest { + + @Test + public void testIsSimpleType() { + Assert.assertTrue(ReflectionUtil.isSimpleType(byte.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(char.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(short.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(int.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(long.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(float.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(double.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(boolean.class)); + + Assert.assertTrue(ReflectionUtil.isSimpleType(Byte.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Character.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Short.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Integer.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Long.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Float.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Double.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Boolean.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(String.class)); + + Assert.assertFalse(ReflectionUtil.isSimpleType(Object.class)); + Assert.assertFalse(ReflectionUtil.isSimpleType(BaseUnitTest.class)); + } + + @Test + public void testGetMethodsAnnotatedWith() { + List methods; + + methods = ReflectionUtil.getMethodsAnnotatedWith(Sub.class, + PerfUtil.Watched.class, + false); + methods.sort((m1, m2) -> m1.getName().compareTo(m2.getName())); + Assert.assertEquals(2, methods.size()); + Assert.assertEquals("func1", methods.get(0).getName()); + Assert.assertEquals("func3", methods.get(1).getName()); + + + methods = ReflectionUtil.getMethodsAnnotatedWith(Sub.class, + PerfUtil.Watched.class, + true); + methods.sort((m1, m2) -> m1.getName().compareTo(m2.getName())); + Assert.assertEquals(3, methods.size()); + Assert.assertEquals("func", methods.get(0).getName()); + Assert.assertEquals("func1", methods.get(1).getName()); + Assert.assertEquals("func3", methods.get(2).getName()); + } + + @Test + public void testClasses() throws IOException { + @SuppressWarnings("unchecked") + List classes = IteratorUtils.toList(ReflectionUtil.classes( + "org.apache.hugegraph.util")); + Assert.assertEquals(19, classes.size()); + classes.sort(Comparator.comparing(ClassInfo::getName)); + Assert.assertEquals("org.apache.hugegraph.util.Bytes", + classes.get(0).getName()); + Assert.assertEquals("org.apache.hugegraph.util.CheckSocket", + classes.get(1).getName()); + Assert.assertEquals("org.apache.hugegraph.util.CollectionUtil", + classes.get(2).getName()); + Assert.assertEquals("org.apache.hugegraph.util.DateUtil", + classes.get(3).getName()); + } + + @Test + public void testSuperClasses() throws NotFoundException { + List classes = ReflectionUtil.superClasses(Sub.class.getName()); + Assert.assertEquals(2, classes.size()); + classes.sort(String::compareTo); + Assert.assertEquals(Object.class.getName(), classes.get(0)); + Assert.assertEquals(Base.class.getName(), classes.get(1)); + } + + @Test + public void testNestedClasses() throws NotFoundException { + List classes = ReflectionUtil.nestedClasses( + TestClass.class.getName()); + Assert.assertEquals(5, classes.size()); + classes.sort(String::compareTo); + Assert.assertEquals(Bar.class.getName(), classes.get(0)); + Assert.assertEquals(Base.class.getName(), classes.get(1)); + Assert.assertEquals(Foo.class.getName(), classes.get(2)); + Assert.assertEquals(ManuallyProfile.class.getName(), classes.get(3)); + Assert.assertEquals(Sub.class.getName(), classes.get(4)); + } + + @Test + public void testPackageName() { + String clazz = "org.apache.hugegraph.unit.perf.testclass2.Test"; + Assert.assertEquals("org.apache.hugegraph.unit.perf.testclass2", + ReflectionUtil.packageName(clazz)); + + clazz = "org.apache.hugegraph.unit.perf.testclass2.Test$Bar"; + Assert.assertEquals("org.apache.hugegraph.unit.perf.testclass2", + ReflectionUtil.packageName(clazz)); + + clazz = "org.apache.hugegraph.unit.perf.testclass.Test$Bar"; + Assert.assertEquals("org.apache.hugegraph.unit.perf.testclass", + ReflectionUtil.packageName(clazz)); + + clazz = "org.apache.hugegraph.unit.perf.testclass..Test$Bar"; + Assert.assertEquals("org.apache.hugegraph.unit.perf.testclass.", + ReflectionUtil.packageName(clazz)); + + clazz = "com"; + Assert.assertEquals("", ReflectionUtil.packageName(clazz)); + + clazz = "com."; + Assert.assertEquals("com", ReflectionUtil.packageName(clazz)); + + clazz = "Test"; + Assert.assertEquals("", ReflectionUtil.packageName(clazz)); + + clazz = ".Test"; + Assert.assertEquals("", ReflectionUtil.packageName(clazz)); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/StringUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/StringUtilTest.java new file mode 100644 index 0000000000..c7aab1532c --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/StringUtilTest.java @@ -0,0 +1,160 @@ +/* + * 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.unit.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.util.StringUtil; +import org.apache.hugegraph.util.StringUtil.Chars; +import org.junit.Test; + +import com.google.common.base.Splitter; + +public class StringUtilTest { + + @Test + public void testSplit() { + Assert.assertArrayEquals(new String[]{"1", "2", "3"}, + StringUtil.split("1, 2, 3", ", ")); + Assert.assertArrayEquals(new String[]{"1", "1", "1"}, + StringUtil.split("1 1 1", " ")); + Assert.assertArrayEquals(new String[]{"", "", ""}, + StringUtil.split("111", "1")); + + Assert.assertEquals(guavaSplit("123", " "), + toStringList(StringUtil.split("123", " "))); + Assert.assertEquals(guavaSplit("1 2 3", " "), + toStringList(StringUtil.split("1 2 3", " "))); + Assert.assertEquals(guavaSplit("1:2:3", ":"), + toStringList(StringUtil.split("1:2:3", ":"))); + Assert.assertEquals(guavaSplit("1::2:3", ":"), + toStringList(StringUtil.split("1::2:3", ":"))); + Assert.assertEquals(guavaSplit("1::2::3", ":"), + toStringList(StringUtil.split("1::2::3", ":"))); + Assert.assertEquals(guavaSplit("1::2::3", "::"), + toStringList(StringUtil.split("1::2::3", "::"))); + Assert.assertEquals(guavaSplit("1:|2|:3", "|"), + toStringList(StringUtil.split("1:|2|:3", "|"))); + Assert.assertEquals(guavaSplit("1\t2\t3", "\t"), + toStringList(StringUtil.split("1\t2\t3", "\t"))); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + StringUtil.split("123", ""); + }); + } + + @Test + public void testSplitToCharsArray() { + Assert.assertArrayEquals(Chars.of("1", "2", "3"), + StringUtil.splitToCharsArray("1, 2, 3", ", ")); + Assert.assertArrayEquals(Chars.of("1", "1", "1"), + StringUtil.splitToCharsArray("1 1 1", " ")); + Assert.assertArrayEquals(Chars.of("", "", ""), + StringUtil.splitToCharsArray("111", "1")); + + Assert.assertArrayEquals(new Chars[]{Chars.of("123")}, + StringUtil.splitToCharsArray("123", " ")); + Assert.assertArrayEquals(Chars.of("1", "", "2", "3"), + StringUtil.splitToCharsArray("1::2:3", ":")); + Assert.assertArrayEquals(Chars.of("1", "", "2", "", "3"), + StringUtil.splitToCharsArray("1::2::3", ":")); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + StringUtil.splitToCharsArray("123", ""); + }); + } + + @Test + public void testCharsCharAt() { + Chars chars = Chars.of("123"); + Assert.assertEquals('1', chars.charAt(0)); + Assert.assertEquals('2', chars.charAt(1)); + Assert.assertEquals('3', chars.charAt(2)); + + Assert.assertThrows(ArrayIndexOutOfBoundsException.class, () -> { + chars.charAt(3); + }); + Assert.assertThrows(ArrayIndexOutOfBoundsException.class, () -> { + chars.charAt(-1); + }); + } + + @Test + public void testCharsSubSequence() { + Chars chars = Chars.of("123"); + Assert.assertEquals(Chars.of("1"), chars.subSequence(0, 1)); + Assert.assertEquals(Chars.of("12"), chars.subSequence(0, 2)); + Assert.assertEquals(Chars.of("2"), chars.subSequence(1, 2)); + Assert.assertEquals(Chars.of("23"), chars.subSequence(1, 3)); + Assert.assertEquals(Chars.of("123"), chars.subSequence(0, 3)); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + chars.subSequence(2, 1); + }, e -> { + Assert.assertContains("Invalid end parameter 1", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + chars.subSequence(-1, 2); + }, e -> { + Assert.assertContains("Invalid start parameter -1", e.getMessage()); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + chars.subSequence(1, -1); + }, e -> { + Assert.assertContains("Invalid end parameter -1", e.getMessage()); + }); + } + + @Test + public void testCharsEquals() { + Chars chars1 = Chars.of("123"); + Chars chars2 = Chars.of("123"); + Chars chars3 = Chars.of("12"); + + Assert.assertEquals(chars1, chars2); + Assert.assertNotEquals(chars1, chars3); + Assert.assertNotEquals(chars1, "123"); + Assert.assertNotEquals(chars1, null); + } + + @Test + public void testCharsHashCode() { + Chars chars1 = Chars.of("123"); + Chars chars2 = Chars.of("123"); + Chars chars3 = Chars.of("12"); + + Assert.assertEquals(chars1.hashCode(), chars2.hashCode()); + Assert.assertEquals(chars1.hashCode(), "123".hashCode()); + Assert.assertNotEquals(chars1.hashCode(), chars3.hashCode()); + } + + private static List guavaSplit(String line, String delimiter) { + return Splitter.on(delimiter).splitToList(line); + } + + private static List toStringList(String[] stringArray) { + List results = new ArrayList<>(stringArray.length); + Collections.addAll(results, stringArray); + return results; + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/TimeUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/TimeUtilTest.java new file mode 100644 index 0000000000..2fc34f0bb5 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/TimeUtilTest.java @@ -0,0 +1,89 @@ +/* + * 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.unit.util; + +import java.util.Date; + +import org.junit.Test; + +import org.apache.hugegraph.util.TimeUtil; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; + +public class TimeUtilTest extends BaseUnitTest { + + @Test + public void testTimeGen() { + long time = TimeUtil.timeGen(); + long base = TimeUtil.BASE_TIME; + long difference = time - base - System.currentTimeMillis(); + Assert.assertTrue(difference < 1000); + } + + @Test + public void testTimeGenWithDate() { + @SuppressWarnings("deprecation") + Date date = new Date(2019 - 1900, 2, 28); + long time = TimeUtil.timeGen(date); + Assert.assertEquals(41904000000L, time); + } + + @Test + public void testTimeGenWithLong() { + long date = TimeUtil.BASE_TIME + 123L; + long time = TimeUtil.timeGen(date); + Assert.assertEquals(123L, time); + } + + @Test + public void testTillNextMillis() { + for (int i = 0; i < 100; i++) { + long lastTimestamp = TimeUtil.timeGen(); + long time = TimeUtil.tillNextMillis(lastTimestamp); + Assert.assertNotEquals(lastTimestamp, time); + } + } + + @Test + public void testReadableTime() { + Assert.assertEquals("0.001s", TimeUtil.readableTime(1)); + Assert.assertEquals("0.999s", TimeUtil.readableTime(999)); + Assert.assertEquals("1s", TimeUtil.readableTime(1000)); + Assert.assertEquals("1.5s", TimeUtil.readableTime(1500)); + Assert.assertEquals("15s", TimeUtil.readableTime(15 * 1000)); + Assert.assertEquals("59.99s", TimeUtil.readableTime(59990)); + Assert.assertEquals("1m", TimeUtil.readableTime(60000)); + // Ignore milliseconds part + Assert.assertEquals("1m", TimeUtil.readableTime(60000 + 100)); + Assert.assertEquals("1m 1s", TimeUtil.readableTime(60000 + 1000)); + Assert.assertEquals("1m 1s", TimeUtil.readableTime(60000 + 1200)); + Assert.assertEquals("59m", TimeUtil.readableTime(59 * 60 * 1000)); + Assert.assertEquals("1h", TimeUtil.readableTime(60 * 60 * 1000)); + Assert.assertEquals("1h 1m", TimeUtil.readableTime(60 * 60 * 1000 + + 60 * 1000)); + Assert.assertEquals("23h 59m 59s", TimeUtil.readableTime( + 23 * 60 * 60 * 1000 + + 59 * 60 * 1000 + + 59 * 1000)); + Assert.assertEquals("24h", TimeUtil.readableTime(24 * 60 * 60 * 1000)); + Assert.assertEquals("25h 1m 1s", TimeUtil.readableTime( + 25 * 60 * 60 * 1000 + + 1 * 60 * 1000 + + 1 * 1200)); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/UnitUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/UnitUtilTest.java new file mode 100644 index 0000000000..56eb73f4d4 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/UnitUtilTest.java @@ -0,0 +1,665 @@ +/* + * 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.unit.util; + +import org.junit.Test; + +import org.apache.hugegraph.util.Bytes; +import org.apache.hugegraph.util.UnitUtil; +import org.apache.hugegraph.testutil.Assert; + +public class UnitUtilTest { + + @Test + public void testBytesToMB() { + double value = UnitUtil.bytesToMB(0L); + Assert.assertEquals(0d, value, 0d); + + // KB + value = UnitUtil.bytesToMB(1 * Bytes.KB); + Assert.assertEquals(0d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.KB * 10); + Assert.assertEquals(0.01d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.KB * 100); + Assert.assertEquals(0.1d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.KB * (long) (134 * 1.024)); + Assert.assertEquals(0.13d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.KB * (long) (135 * 1.024)); + Assert.assertEquals(0.13d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.KB * (long) (136 * 1.024)); + Assert.assertEquals(0.14d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.KB * (long) (144 * 1.024)); + Assert.assertEquals(0.14d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.KB * (long) (754 * 1.024)); + Assert.assertEquals(0.75d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.KB * (long) (755 * 1.024)); + Assert.assertEquals(0.75d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.KB * (long) (756 * 1.024)); + Assert.assertEquals(0.76d, value, 0d); + + // MB + value = UnitUtil.bytesToMB(Bytes.MB * 1); + Assert.assertEquals(1d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.MB * 13); + Assert.assertEquals(13d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.MB * 1357); + Assert.assertEquals(1357d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.MB * 1357924680); + Assert.assertEquals(1357924680d, value, 0d); + + value = UnitUtil.bytesToMB(Bytes.MB * 1357924680246L); + Assert.assertEquals(1357924680246d, value, 0d); + } + + @Test + public void testBytesToGB() { + double value = UnitUtil.bytesToGB(0L); + Assert.assertEquals(0d, value, 0d); + + // MB + value = UnitUtil.bytesToGB(1 * Bytes.MB); + Assert.assertEquals(0d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.MB * 10); + Assert.assertEquals(0.01d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.MB * 100); + Assert.assertEquals(0.10d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.MB * (long) (134 * 1.024)); + Assert.assertEquals(0.13d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.MB * (long) (135 * 1.024)); + Assert.assertEquals(0.13d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.MB * (long) (136 * 1.024)); + Assert.assertEquals(0.14d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.MB * (long) (144 * 1.024)); + Assert.assertEquals(0.14d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.MB * (long) (754 * 1.024)); + Assert.assertEquals(0.75d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.MB * (long) (755 * 1.024)); + Assert.assertEquals(0.75d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.MB * (long) (756 * 1.024)); + Assert.assertEquals(0.76d, value, 0d); + + // GB + value = UnitUtil.bytesToGB(Bytes.GB * 1); + Assert.assertEquals(1d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.GB * 13); + Assert.assertEquals(13d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.GB * 1357); + Assert.assertEquals(1357d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.GB * 1357924680); + Assert.assertEquals(1357924680d, value, 0d); + + value = UnitUtil.bytesToGB(Bytes.GB * 7357924680L); + Assert.assertEquals(7357924680d, value, 0d); + + // Bytes overflow long value + value = UnitUtil.bytesToGB(Bytes.GB * 9357924680L); + Assert.assertEquals(-7.821944504E9, value, 0d); + } + + @Test + public void testBytesToReadableString() { + String value = UnitUtil.bytesToReadableString(0L); + Assert.assertEquals("0 B", value); + + // B + value = UnitUtil.bytesToReadableString(1); + Assert.assertEquals("1 B", value); + + value = UnitUtil.bytesToReadableString(3); + Assert.assertEquals("3 B", value); + + value = UnitUtil.bytesToReadableString(10); + Assert.assertEquals("10 B", value); + + value = UnitUtil.bytesToReadableString(100); + Assert.assertEquals("100 B", value); + + value = UnitUtil.bytesToReadableString(1000); + Assert.assertEquals("1000 B", value); + + value = UnitUtil.bytesToReadableString(1023); + Assert.assertEquals("1023 B", value); + + // KB + value = UnitUtil.bytesToReadableString(1024); + Assert.assertEquals("1 KB", value); + + value = UnitUtil.bytesToReadableString(Bytes.KB + 1); + Assert.assertEquals("1.0 KB", value); + + value = UnitUtil.bytesToReadableString(Bytes.KB + 10); + Assert.assertEquals("1.01 KB", value); + + value = UnitUtil.bytesToReadableString(Bytes.KB + 20); + Assert.assertEquals("1.02 KB", value); + + value = UnitUtil.bytesToReadableString(Bytes.KB + 100); + Assert.assertEquals("1.1 KB", value); + + value = UnitUtil.bytesToReadableString(Bytes.KB + 123); + Assert.assertEquals("1.12 KB", value); + + value = UnitUtil.bytesToReadableString(Bytes.KB + 129); + Assert.assertEquals("1.13 KB", value); + + value = UnitUtil.bytesToReadableString(Bytes.KB * 8 + + (long) (755 * 1.024)); + Assert.assertEquals("8.75 KB", value); + + value = UnitUtil.bytesToReadableString(Bytes.KB * 168 + + (long) (756 * 1.024)); + Assert.assertEquals("168.76 KB", value); + + // MB + value = UnitUtil.bytesToReadableString(Bytes.KB * 1024); + Assert.assertEquals("1 MB", value); + + value = UnitUtil.bytesToReadableString(Bytes.MB + 1 * Bytes.KB); + Assert.assertEquals("1.0 MB", value); + + value = UnitUtil.bytesToReadableString(Bytes.MB + 10 * Bytes.KB); + Assert.assertEquals("1.01 MB", value); + + value = UnitUtil.bytesToReadableString(Bytes.MB + 20 * Bytes.KB); + Assert.assertEquals("1.02 MB", value); + + value = UnitUtil.bytesToReadableString(Bytes.MB + 100 * Bytes.KB); + Assert.assertEquals("1.1 MB", value); + + value = UnitUtil.bytesToReadableString(Bytes.MB + 123 * Bytes.KB); + Assert.assertEquals("1.12 MB", value); + + value = UnitUtil.bytesToReadableString(Bytes.MB + 129 * Bytes.KB); + Assert.assertEquals("1.13 MB", value); + + value = UnitUtil.bytesToReadableString(Bytes.MB * 8 + + (long) (755 * 1.024) * Bytes.KB); + Assert.assertEquals("8.75 MB", value); + + value = UnitUtil.bytesToReadableString(Bytes.MB * 168 + + (long) (756 * 1.024) * Bytes.KB); + Assert.assertEquals("168.76 MB", value); + + // GB + value = UnitUtil.bytesToReadableString(Bytes.MB * 1024); + Assert.assertEquals("1 GB", value); + + value = UnitUtil.bytesToReadableString(Bytes.GB + 1 * Bytes.MB); + Assert.assertEquals("1.0 GB", value); + + value = UnitUtil.bytesToReadableString(Bytes.GB + 10 * Bytes.MB); + Assert.assertEquals("1.01 GB", value); + + value = UnitUtil.bytesToReadableString(Bytes.GB + 20 * Bytes.MB); + Assert.assertEquals("1.02 GB", value); + + value = UnitUtil.bytesToReadableString(Bytes.GB + 100 * Bytes.MB); + Assert.assertEquals("1.1 GB", value); + + value = UnitUtil.bytesToReadableString(Bytes.GB + 123 * Bytes.MB); + Assert.assertEquals("1.12 GB", value); + + value = UnitUtil.bytesToReadableString(Bytes.GB + 129 * Bytes.MB); + Assert.assertEquals("1.13 GB", value); + + value = UnitUtil.bytesToReadableString(Bytes.GB * 8 + + (long) (755 * 1.024) * Bytes.MB); + Assert.assertEquals("8.75 GB", value); + + value = UnitUtil.bytesToReadableString(Bytes.GB * 168 + + (long) (756 * 1.024) * Bytes.MB); + Assert.assertEquals("168.76 GB", value); + + // TB + value = UnitUtil.bytesToReadableString(Bytes.GB * 1024); + Assert.assertEquals("1 TB", value); + + value = UnitUtil.bytesToReadableString(Bytes.TB + 1 * Bytes.GB); + Assert.assertEquals("1.0 TB", value); + + value = UnitUtil.bytesToReadableString(Bytes.TB + 10 * Bytes.GB); + Assert.assertEquals("1.01 TB", value); + + value = UnitUtil.bytesToReadableString(Bytes.TB + 20 * Bytes.GB); + Assert.assertEquals("1.02 TB", value); + + value = UnitUtil.bytesToReadableString(Bytes.TB + 100 * Bytes.GB); + Assert.assertEquals("1.1 TB", value); + + value = UnitUtil.bytesToReadableString(Bytes.TB + 123 * Bytes.GB); + Assert.assertEquals("1.12 TB", value); + + value = UnitUtil.bytesToReadableString(Bytes.TB + 129 * Bytes.GB); + Assert.assertEquals("1.13 TB", value); + + value = UnitUtil.bytesToReadableString(Bytes.TB * 8 + + (long) (755 * 1.024) * Bytes.GB); + Assert.assertEquals("8.75 TB", value); + + value = UnitUtil.bytesToReadableString(Bytes.TB * 168 + + (long) (756 * 1.024) * Bytes.GB); + Assert.assertEquals("168.76 TB", value); + + // PB + value = UnitUtil.bytesToReadableString(Bytes.TB * 1024); + Assert.assertEquals("1 PB", value); + + value = UnitUtil.bytesToReadableString(Bytes.PB + 1 * Bytes.TB); + Assert.assertEquals("1.0 PB", value); + + value = UnitUtil.bytesToReadableString(Bytes.PB + 10 * Bytes.TB); + Assert.assertEquals("1.01 PB", value); + + value = UnitUtil.bytesToReadableString(Bytes.PB + 20 * Bytes.TB); + Assert.assertEquals("1.02 PB", value); + + value = UnitUtil.bytesToReadableString(Bytes.PB + 100 * Bytes.TB); + Assert.assertEquals("1.1 PB", value); + + value = UnitUtil.bytesToReadableString(Bytes.PB + 123 * Bytes.TB); + Assert.assertEquals("1.12 PB", value); + + value = UnitUtil.bytesToReadableString(Bytes.PB + 129 * Bytes.TB); + Assert.assertEquals("1.13 PB", value); + + value = UnitUtil.bytesToReadableString(Bytes.PB * 8 + + (long) (755 * 1.024) * Bytes.TB); + Assert.assertEquals("8.75 PB", value); + + value = UnitUtil.bytesToReadableString(Bytes.PB * 168 + + (long) (756 * 1.024) * Bytes.TB); + Assert.assertEquals("168.76 PB", value); + + // EB + value = UnitUtil.bytesToReadableString(Bytes.PB * 1024); + Assert.assertEquals("1 EB", value); + + value = UnitUtil.bytesToReadableString(Bytes.EB + 1 * Bytes.PB); + Assert.assertEquals("1.0 EB", value); + + value = UnitUtil.bytesToReadableString(Bytes.EB + 10 * Bytes.PB); + Assert.assertEquals("1.01 EB", value); + + value = UnitUtil.bytesToReadableString(Bytes.EB + 20 * Bytes.PB); + Assert.assertEquals("1.02 EB", value); + + value = UnitUtil.bytesToReadableString(Bytes.EB + 100 * Bytes.PB); + Assert.assertEquals("1.1 EB", value); + + value = UnitUtil.bytesToReadableString(Bytes.EB + 123 * Bytes.PB); + Assert.assertEquals("1.12 EB", value); + + value = UnitUtil.bytesToReadableString(Bytes.EB + 129 * Bytes.PB); + Assert.assertEquals("1.13 EB", value); + + value = UnitUtil.bytesToReadableString(Bytes.EB * 7 + + (long) (755 * 1.024) * Bytes.PB); + Assert.assertEquals("7.75 EB", value); + + // Bytes overflow long value + value = UnitUtil.bytesToReadableString(Bytes.EB * 8); + Assert.assertEquals("0 B", value); + } + + @Test + public void testBytesFromReadableString() { + // B + Assert.assertEquals(0L, UnitUtil.bytesFromReadableString("0 B")); + Assert.assertEquals(1L, UnitUtil.bytesFromReadableString("1 Bytes")); + Assert.assertEquals(3L, UnitUtil.bytesFromReadableString("3 bytes")); + Assert.assertEquals(10L, UnitUtil.bytesFromReadableString("10 Byte")); + Assert.assertEquals(100L, UnitUtil.bytesFromReadableString("100 byte")); + Assert.assertEquals(1000L, UnitUtil.bytesFromReadableString("1000 b")); + Assert.assertEquals(1023L, UnitUtil.bytesFromReadableString("1023 B")); + + Assert.assertEquals(1024L, UnitUtil.bytesFromReadableString("1024 B")); + Assert.assertEquals(10245678L, + UnitUtil.bytesFromReadableString("10245678 B")); + Assert.assertEquals(102456789012L, + UnitUtil.bytesFromReadableString("102456789012 B")); + + Assert.assertEquals(1L, UnitUtil.bytesFromReadableString("1 B")); + Assert.assertEquals(1L, UnitUtil.bytesFromReadableString("1 B ")); + Assert.assertEquals(-2L, UnitUtil.bytesFromReadableString("-2 B")); + + // KB + Assert.assertEquals(0L, UnitUtil.bytesFromReadableString("0 KB")); + Assert.assertEquals(Bytes.KB * 1L, + UnitUtil.bytesFromReadableString("1 KB")); + Assert.assertEquals((long) (Bytes.KB * 3.14), + UnitUtil.bytesFromReadableString("3.14 KB")); + Assert.assertEquals(Bytes.KB * 10L, + UnitUtil.bytesFromReadableString("10 kB")); + Assert.assertEquals(Bytes.KB * 100L, + UnitUtil.bytesFromReadableString("100 KiB")); + Assert.assertEquals(Bytes.KB * 1000L, + UnitUtil.bytesFromReadableString("1000 kb")); + Assert.assertEquals(Bytes.KB * 1023L, + UnitUtil.bytesFromReadableString("1023 kib")); + Assert.assertEquals(Bytes.KB * 1234567890L, + UnitUtil.bytesFromReadableString("1234567890 Kib")); + // MB + Assert.assertEquals(0L, UnitUtil.bytesFromReadableString("0 MB")); + Assert.assertEquals(Bytes.MB * 1L, + UnitUtil.bytesFromReadableString("1 MB")); + Assert.assertEquals((long) (Bytes.MB * 3.14), + UnitUtil.bytesFromReadableString("3.14 MB")); + Assert.assertEquals(Bytes.MB * 10L, + UnitUtil.bytesFromReadableString("10 mB")); + Assert.assertEquals(Bytes.MB * 100L, + UnitUtil.bytesFromReadableString("100 MiB")); + Assert.assertEquals(Bytes.MB * 1000L, + UnitUtil.bytesFromReadableString("1000 mib")); + Assert.assertEquals(Bytes.MB * 1023L, + UnitUtil.bytesFromReadableString("1023 MIB")); + Assert.assertEquals(Bytes.MB * 1234567890L, + UnitUtil.bytesFromReadableString("1234567890 Mb")); + + // GB + Assert.assertEquals(0L, UnitUtil.bytesFromReadableString("0 GB")); + Assert.assertEquals(Bytes.GB * 1L, + UnitUtil.bytesFromReadableString("1 GB")); + Assert.assertEquals((long) (Bytes.GB * 3.14), + UnitUtil.bytesFromReadableString("3.14 GB")); + Assert.assertEquals(Bytes.GB * 10L, + UnitUtil.bytesFromReadableString("10 gB")); + Assert.assertEquals(Bytes.GB * 100L, + UnitUtil.bytesFromReadableString("100 GiB")); + Assert.assertEquals(Bytes.GB * 1000L, + UnitUtil.bytesFromReadableString("1000 gib")); + Assert.assertEquals(Bytes.GB * 1023L, + UnitUtil.bytesFromReadableString("1023 GIB")); + Assert.assertEquals(Bytes.GB * 1234567890L, + UnitUtil.bytesFromReadableString("1234567890 Gb")); + + // TB + Assert.assertEquals(0L, UnitUtil.bytesFromReadableString("0 TB")); + Assert.assertEquals(Bytes.TB * 1L, + UnitUtil.bytesFromReadableString("1 TB")); + Assert.assertEquals((long) (Bytes.TB * 3.14), + UnitUtil.bytesFromReadableString("3.14 TB")); + Assert.assertEquals(Bytes.TB * 10L, + UnitUtil.bytesFromReadableString("10 tB")); + Assert.assertEquals(Bytes.TB * 100L, + UnitUtil.bytesFromReadableString("100 TiB")); + Assert.assertEquals(Bytes.TB * 1000L, + UnitUtil.bytesFromReadableString("1000 tib")); + Assert.assertEquals(Bytes.TB * 1023L, + UnitUtil.bytesFromReadableString("1023 TIB")); + Assert.assertEquals(Bytes.TB * 123456L, + UnitUtil.bytesFromReadableString("123456 Tb")); + + // PB + Assert.assertEquals(0L, UnitUtil.bytesFromReadableString("0 PB")); + Assert.assertEquals(Bytes.PB * 1L, + UnitUtil.bytesFromReadableString("1 PB")); + Assert.assertEquals((long) (Bytes.PB * 3.14), + UnitUtil.bytesFromReadableString("3.14 PB")); + Assert.assertEquals(Bytes.PB * 10L, + UnitUtil.bytesFromReadableString("10 pB")); + Assert.assertEquals(Bytes.PB * 100L, + UnitUtil.bytesFromReadableString("100 PiB")); + Assert.assertEquals(Bytes.PB * 1000L, + UnitUtil.bytesFromReadableString("1000 pib")); + Assert.assertEquals(Bytes.PB * 1023L, + UnitUtil.bytesFromReadableString("1023 PIB")); + Assert.assertEquals(Bytes.PB * 8024L, + UnitUtil.bytesFromReadableString("8024 PIB")); + + // EB + Assert.assertEquals(0L, UnitUtil.bytesFromReadableString("0 EB")); + Assert.assertEquals(Bytes.EB * 1L, + UnitUtil.bytesFromReadableString("1 EB")); + Assert.assertEquals((long) (Bytes.EB * 3.14), + UnitUtil.bytesFromReadableString("3.14 EB")); + Assert.assertEquals((long) (Bytes.EB * 5.01), + UnitUtil.bytesFromReadableString("5.01 eB")); + Assert.assertEquals((long) (Bytes.EB * 6.28), + UnitUtil.bytesFromReadableString("6.28 EiB")); + Assert.assertEquals((long) (Bytes.EB * 7.9876), + UnitUtil.bytesFromReadableString("7.9876 eib")); + Assert.assertEquals((long) (Bytes.EB * 8.0), + UnitUtil.bytesFromReadableString("8.0 EIB")); // max + } + + @Test + public void testBytesFromReadableStringWithInvalidFormat() { + // No space + Assert.assertThrows(IllegalArgumentException.class, () -> { + UnitUtil.bytesFromReadableString("1kb"); + }, e -> { + Assert.assertContains("Invalid readable bytes '1kb'", + e.getMessage()); + }); + + // Invalid unit + Assert.assertThrows(IllegalArgumentException.class, () -> { + UnitUtil.bytesFromReadableString("1 aBc"); + }, e -> { + Assert.assertContains("Unrecognized unit aBc", e.getMessage()); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + UnitUtil.bytesFromReadableString("1 k"); + }, e -> { + Assert.assertContains("Unrecognized unit k", e.getMessage()); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + UnitUtil.bytesFromReadableString("1 m"); + }, e -> { + Assert.assertContains("Unrecognized unit m", e.getMessage()); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + UnitUtil.bytesFromReadableString("1 2 MB"); + }, e -> { + Assert.assertContains("Unrecognized unit 2 MB", e.getMessage()); + }); + + // Invalid number + Assert.assertThrows(IllegalArgumentException.class, () -> { + UnitUtil.bytesFromReadableString("2b kb"); + }, e -> { + Assert.assertContains("Invalid parameter(not number): '2b kb'", + e.getMessage()); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + UnitUtil.bytesFromReadableString("2.3.4 kb"); + }, e -> { + Assert.assertContains("Invalid parameter(not number): '2.3.4 kb'", + e.getMessage()); + }); + + // Bytes overflow long value + Assert.assertThrows(IllegalArgumentException.class, () -> { + UnitUtil.bytesFromReadableString("8.1 EIB"); + }, e -> { + Assert.assertContains("The value 9.33866418731546E18 from " + + "parameter '8.1 EIB' is out of range", + e.getMessage()); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + UnitUtil.bytesFromReadableString("9024 Pb"); + }, e -> { + Assert.assertContains("is out of range", e.getMessage()); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + UnitUtil.bytesFromReadableString("12345678 Tb"); + }, e -> { + Assert.assertContains("is out of range", e.getMessage()); + }); + } + + @Test + public void testTimestampToReadableString() { + Assert.assertEquals("0ms", + UnitUtil.timestampToReadableString(0L)); + Assert.assertEquals("1ms", + UnitUtil.timestampToReadableString(1L)); + Assert.assertEquals("100ms", + UnitUtil.timestampToReadableString(100L)); + Assert.assertEquals("999ms", + UnitUtil.timestampToReadableString(999L)); + + Assert.assertEquals("1s", + UnitUtil.timestampToReadableString(1000L)); + Assert.assertEquals("10s", + UnitUtil.timestampToReadableString(10000L)); + Assert.assertEquals("1s1ms", + UnitUtil.timestampToReadableString(1001L)); + Assert.assertEquals("1s200ms", + UnitUtil.timestampToReadableString(1200L)); + Assert.assertEquals("6s789ms", + UnitUtil.timestampToReadableString(6789L)); + Assert.assertEquals("59s789ms", + UnitUtil.timestampToReadableString(59789L)); + + Assert.assertEquals("1m0s", + UnitUtil.timestampToReadableString(60789L)); + Assert.assertEquals("1m1s", + UnitUtil.timestampToReadableString(61789L)); + Assert.assertEquals("1m2s", + UnitUtil.timestampToReadableString(62000L)); + Assert.assertEquals("2m2s", + UnitUtil.timestampToReadableString(122000L)); + Assert.assertEquals("2m12s", + UnitUtil.timestampToReadableString(132000L)); + Assert.assertEquals("59m59s", + UnitUtil.timestampToReadableString(3599000L)); + + Assert.assertEquals("1h0m0s", + UnitUtil.timestampToReadableString(3600000L)); + Assert.assertEquals("1h0m23s", + UnitUtil.timestampToReadableString(3623000L)); + Assert.assertEquals("1h1m23s", + UnitUtil.timestampToReadableString(3683000L)); + Assert.assertEquals("1h24m43s", + UnitUtil.timestampToReadableString(5083000L)); + Assert.assertEquals("23h59m59s", + UnitUtil.timestampToReadableString(86399000L)); + + Assert.assertEquals("1d0h0m0s", + UnitUtil.timestampToReadableString(86400000L)); + Assert.assertEquals("1d1h24m43s", + UnitUtil.timestampToReadableString(91483000L)); + Assert.assertEquals("1d1h24m43s", + UnitUtil.timestampToReadableString(91483000L)); + + Assert.assertEquals("30d0h0m0s", + UnitUtil.timestampToReadableString(2592000000L)); + Assert.assertEquals("30d23h59m59s", + UnitUtil.timestampToReadableString(2678399000L)); + Assert.assertEquals("130d23h59m59s", + UnitUtil.timestampToReadableString(11318399000L)); + Assert.assertEquals("1130d23h59m59s", + UnitUtil.timestampToReadableString(97718399000L)); + } + + @Test + public void testTimestampFromReadableString() { + Assert.assertEquals(0L, + UnitUtil.timestampFromReadableString("0ms")); + Assert.assertEquals(1L, + UnitUtil.timestampFromReadableString("1ms")); + Assert.assertEquals(100L, + UnitUtil.timestampFromReadableString("100ms")); + Assert.assertEquals(999L, + UnitUtil.timestampFromReadableString("999ms")); + Assert.assertEquals(1001L, + UnitUtil.timestampFromReadableString("1001ms")); + + Assert.assertEquals(0L, + UnitUtil.timestampFromReadableString("0s")); + Assert.assertEquals(1000L, + UnitUtil.timestampFromReadableString("1s")); + Assert.assertEquals(10000L, + UnitUtil.timestampFromReadableString("10s")); + Assert.assertEquals(1001L, + UnitUtil.timestampFromReadableString("1s1ms")); + Assert.assertEquals(1200L, + UnitUtil.timestampFromReadableString("1s200ms")); + Assert.assertEquals(6789L, + UnitUtil.timestampFromReadableString("6s789ms")); + Assert.assertEquals(59789L, + UnitUtil.timestampFromReadableString("59s789ms")); + Assert.assertEquals(59789L, + UnitUtil.timestampFromReadableString("59s2789ms")); + + Assert.assertEquals(60000L, + UnitUtil.timestampFromReadableString("1m0s")); + Assert.assertEquals(61000L, + UnitUtil.timestampFromReadableString("1m1s")); + Assert.assertEquals(62000L, + UnitUtil.timestampFromReadableString("1m2s")); + Assert.assertEquals(122000L, + UnitUtil.timestampFromReadableString("2m2s")); + Assert.assertEquals(132000L, + UnitUtil.timestampFromReadableString("2m12s")); + Assert.assertEquals(3599000L, + UnitUtil.timestampFromReadableString("59m59s")); + + Assert.assertEquals(3600000L, + UnitUtil.timestampFromReadableString("1h0m0s")); + Assert.assertEquals(3623000L, + UnitUtil.timestampFromReadableString("1h0m23s")); + Assert.assertEquals(3683000L, + UnitUtil.timestampFromReadableString("1h1m23s")); + Assert.assertEquals(5083000L, + UnitUtil.timestampFromReadableString("1h24m43s")); + Assert.assertEquals(86399000L, + UnitUtil.timestampFromReadableString("23h59m59s")); + + Assert.assertEquals(86400000L, + UnitUtil.timestampFromReadableString("1d0h0m0s")); + Assert.assertEquals(91483000L, + UnitUtil.timestampFromReadableString("1d1h24m43s")); + Assert.assertEquals(91483000L, + UnitUtil.timestampFromReadableString("1d1h24m43s")); + + Assert.assertEquals(2592000000L, UnitUtil.timestampFromReadableString( + "30d0h0m0s")); + Assert.assertEquals(2678399000L, UnitUtil.timestampFromReadableString( + "30d23h59m59s")); + Assert.assertEquals(11318399000L, UnitUtil.timestampFromReadableString( + "130d23h59m59s")); + Assert.assertEquals(97718399000L, UnitUtil.timestampFromReadableString( + "1130d23h59m59s")); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/VersionUtilTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/VersionUtilTest.java new file mode 100644 index 0000000000..25f6ef129a --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/util/VersionUtilTest.java @@ -0,0 +1,169 @@ +/* + * 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.unit.util; + +import java.net.MalformedURLException; + +import org.junit.Test; + +import org.apache.hugegraph.util.VersionUtil; +import org.apache.hugegraph.util.VersionUtil.Version; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; + +public class VersionUtilTest extends BaseUnitTest { + + @Test + public void testVersionWithTwoPart() { + Version version = Version.of("0.2"); + + Assert.assertTrue(VersionUtil.match(version, "0", "1")); + Assert.assertTrue(VersionUtil.match(version, "0.0", "1.0")); + Assert.assertTrue(VersionUtil.match(version, "0.1", "0.3")); + Assert.assertTrue(VersionUtil.match(version, "0.2", "0.3")); + Assert.assertTrue(VersionUtil.match(version, "0.2", "0.2.1")); + Assert.assertTrue(VersionUtil.match(version, "0.2", "0.2.01")); + Assert.assertTrue(VersionUtil.match(version, "0.2", "0.10")); + Assert.assertTrue(VersionUtil.match(version, "0.2", "1.0")); + + Assert.assertFalse(VersionUtil.match(version, "1", "0.3")); + Assert.assertFalse(VersionUtil.match(version, "0.3", "0.4")); + Assert.assertFalse(VersionUtil.match(version, "0.2", "0.1")); + Assert.assertFalse(VersionUtil.match(version, "0.2", "0.2")); + Assert.assertFalse(VersionUtil.match(version, "0.2", "0.2.0")); + Assert.assertFalse(VersionUtil.match(version, "0.3", "0.1")); + } + + @Test + public void testVersionWithThreePart() { + Version version = Version.of("3.2.5"); + + Assert.assertTrue(VersionUtil.match(version, "2", "4")); + Assert.assertTrue(VersionUtil.match(version, "3", "4")); + Assert.assertTrue(VersionUtil.match(version, "3.1", "3.3")); + Assert.assertTrue(VersionUtil.match(version, "3.2", "3.3")); + Assert.assertTrue(VersionUtil.match(version, "3.2.4", "3.3")); + Assert.assertTrue(VersionUtil.match(version, "3.2.5", "3.3")); + Assert.assertTrue(VersionUtil.match(version, "3.2.5", "3.2.6")); + Assert.assertTrue(VersionUtil.match(version, "3.2.5", "3.2.10")); + Assert.assertTrue(VersionUtil.match(version, "3.2.5", "3.20.0")); + + Assert.assertFalse(VersionUtil.match(version, "2", "3")); + Assert.assertFalse(VersionUtil.match(version, "3.3", "3.1")); + Assert.assertFalse(VersionUtil.match(version, "3.3", "3.2")); + Assert.assertFalse(VersionUtil.match(version, "3.3", "3.2")); + Assert.assertFalse(VersionUtil.match(version, "3.2.5", "3.2.5")); + Assert.assertFalse(VersionUtil.match(version, "3.2.6", "3.2.5")); + Assert.assertFalse(VersionUtil.match(version, "3.2.6", "3.2.4")); + Assert.assertFalse(VersionUtil.match(version, "3.2.50", "3.2.6")); + Assert.assertFalse(VersionUtil.match(version, "3.20.0", "3.3")); + } + + @Test + public void testVersionGte() { + String version = "0.2"; + + Assert.assertTrue(VersionUtil.gte(version, "0.2")); + Assert.assertTrue(VersionUtil.gte(version, "0.2.0")); + Assert.assertTrue(VersionUtil.gte(version, "0.1")); + Assert.assertTrue(VersionUtil.gte(version, "0.1.9")); + Assert.assertTrue(VersionUtil.gte(version, "0.0.3")); + + Assert.assertFalse(VersionUtil.gte(version, "0.2.0.1")); + Assert.assertFalse(VersionUtil.gte(version, "0.2.1")); + Assert.assertFalse(VersionUtil.gte(version, "0.3")); + Assert.assertFalse(VersionUtil.gte(version, "0.10")); + } + + @Test + public void testVersionCheck() { + Version version = Version.of("0.6.5"); + + VersionUtil.check(version, "0.6", "0.7", "test-component"); + VersionUtil.check(version, "0.6.5", "0.7", "test-component"); + VersionUtil.check(version, "0.6.5", "0.6.6", "test-component"); + + Assert.assertThrows(IllegalStateException.class, () -> { + VersionUtil.check(version, "0.6.5", "0.6.5", "test-component"); + }); + + Assert.assertThrows(IllegalStateException.class, () -> { + VersionUtil.check(version, "0.6.5", "0.6", "test-component"); + }); + + Assert.assertThrows(IllegalStateException.class, () -> { + VersionUtil.check(version, "0.7", "0.6", "test-component"); + }); + + Assert.assertThrows(IllegalStateException.class, () -> { + VersionUtil.check(version, "0.5", "0.6", "test-component"); + }); + + Assert.assertThrows(IllegalStateException.class, () -> { + VersionUtil.check(version, "0.7", "1.0", "test-component"); + }); + } + + @Test + public void testGetImplementationVersion() throws MalformedURLException { + // Can't mock Class: https://github.com/mockito/mockito/issues/1734 + //Class clazz = Mockito.mock(Class.class); + //Mockito.when(clazz.getSimpleName()).thenReturn("fake"); + //Mockito.when(clazz.getResource("fake.class")).thenReturn(manifest); + + String manifestPath = "file:./src/test/resources"; + Assert.assertEquals("1.8.8.0", + VersionUtil.getImplementationVersion(manifestPath)); + + manifestPath = "file:./src/test/resources2"; + Assert.assertNull(VersionUtil.getImplementationVersion(manifestPath)); + } + + @Test + public void testVersion() { + // Test equals + Version v1 = Version.of("0.2.1"); + Version v2 = Version.of("0.2.1"); + Assert.assertEquals(v1, v1); + Assert.assertEquals(v1, v2); + + Version v3 = Version.of("0.2.0"); + Version v4 = Version.of("0.2"); + Assert.assertEquals(v3, v4); + + Version v5 = Version.of("0.2.3"); + Version v6 = Version.of("0.3.2"); + Assert.assertNotEquals(v5, v6); + Assert.assertNotEquals(v5, null); + Assert.assertNotEquals(v5, "0.2.3"); + + // Test hashCode + Assert.assertEquals(1023, v1.hashCode()); + Assert.assertEquals(1023, v2.hashCode()); + Assert.assertEquals(62, v3.hashCode()); + Assert.assertEquals(62, v4.hashCode()); + Assert.assertEquals(2945, v5.hashCode()); + Assert.assertEquals(2015, v6.hashCode()); + + // Test compareTo + Assert.assertEquals(0, v1.compareTo(v2)); + Assert.assertEquals(1, v1.compareTo(v3)); + Assert.assertEquals(-1, v1.compareTo(v5)); + Assert.assertEquals(1, v1.compareTo(null)); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/version/VersionTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/version/VersionTest.java new file mode 100644 index 0000000000..432d66ee31 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/version/VersionTest.java @@ -0,0 +1,36 @@ +/* + * 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.unit.version; + +import org.apache.hugegraph.util.VersionUtil; +import org.junit.Test; + +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.version.CommonVersion; + +public class VersionTest { + + @Test + public void testGetCommonVersion() { + String pomVersion = VersionUtil.getPomVersion(); + Assert.assertNotNull(pomVersion); + String version = CommonVersion.VERSION.get(); + Assert.assertNotNull(version); + Assert.assertEquals(pomVersion, version); + } +} diff --git a/hugegraph-commons/hugegraph-common/src/test/resources/META-INF/MANIFEST.MF b/hugegraph-commons/hugegraph-common/src/test/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..7abb11a917 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/resources/META-INF/MANIFEST.MF @@ -0,0 +1,8 @@ +Manifest-Version: 1.0 +Implementation-Version: 1.8.8.0 +Archiver-Version: Plexus Archiver +Built-By: jermy +Specification-Title: hugegraph-common +Created-By: Apache Maven 3.3.9 +Build-Jdk: 1.8.0_111 +Specification-Version: 1.8.8 diff --git a/hugegraph-commons/hugegraph-common/src/test/resources/create-license.json b/hugegraph-commons/hugegraph-common/src/test/resources/create-license.json new file mode 100644 index 0000000000..c1131312c9 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/resources/create-license.json @@ -0,0 +1,19 @@ +{ + "subject": "hugegraph-evaluation", + "private_alias": "privatekey", + "key_ticket": "a123456", + "store_ticket": "a123456", + "privatekey_path": "src/test/resources/privateKeys.store", + "license_path": "src/test/resources/hugegraph-evaluation.license", + "issued_time": "2019-08-01 00:00:00", + "not_before": "2019-08-01 00:00:00", + "not_after": "2029-08-01 00:00:00", + "consumer_type": "user", + "consumer_amount": 1, + "extra_params": [ + { + "id": "server-1", + "graphs": 3 + } + ] +} diff --git a/hugegraph-commons/hugegraph-common/src/test/resources/log4j2.xml b/hugegraph-commons/hugegraph-common/src/test/resources/log4j2.xml new file mode 100644 index 0000000000..5ada1de623 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/resources/log4j2.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hugegraph-commons/hugegraph-common/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/hugegraph-commons/hugegraph-common/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000000..a76010b24c --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1,17 @@ +# +# 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. +# +mock-maker-inline diff --git a/hugegraph-commons/hugegraph-common/src/test/resources/verify-license.json b/hugegraph-commons/hugegraph-common/src/test/resources/verify-license.json new file mode 100644 index 0000000000..779c5d6883 --- /dev/null +++ b/hugegraph-commons/hugegraph-common/src/test/resources/verify-license.json @@ -0,0 +1,7 @@ +{ + "subject": "hugegraph-evaluation", + "public_alias": "publiccert", + "store_ticket": "a123456", + "publickey_path": "src/test/resources/publicCerts.store", + "license_path": "src/test/resources/hugegraph-evaluation.license" +} diff --git a/hugegraph-commons/hugegraph-dist/release-docs/LICENSE b/hugegraph-commons/hugegraph-dist/release-docs/LICENSE new file mode 100644 index 0000000000..ab02e44829 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/LICENSE @@ -0,0 +1,338 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +============================================================================ + APACHE HUGEGRAPH (Incubating) SUBCOMPONENTS: + + The Apache HugeGraph(Incubating) project contains subcomponents with separate copyright + notices and license terms. Your use of the source code for the these + subcomponents is subject to the terms and conditions of the following + licenses. + + +======================================================================== +Third party Apache 2.0 licenses +======================================================================== + +The following components are provided under the Apache 2.0 License. +See licenses/ for text of these licenses. + + (Apache License, 2.0) Javassist (org.javassist:javassist:3.28.0-GA - http://www.javassist.org/) + (Apache License, Version 2.0) * Apache Commons BeanUtils:- commons-beanutils:commons-beanutils:1.9.4 (https://commons.apache.org/proper/commons-beanutils/) + (Apache License, Version 2.0) * Apache Commons Codec:- commons-codec:commons-codec:1.13 (https://commons.apache.org/proper/commons-codec/) + (Apache License, Version 2.0) * Apache Commons Collections:- commons-collections:commons-collections:3.2.2 (http://commons.apache.org/collections/) + (Apache License, Version 2.0) * Apache Commons Configuration:- commons-configuration:commons-configuration:1.10 (http://commons.apache.org/configuration/)- org.apache.commons:commons-configuration2:2.8.0 (https://commons.apache.org/proper/commons-configuration/) + (Apache License, Version 2.0) * Apache Commons IO:- commons-io:commons-io:2.7 (https://commons.apache.org/proper/commons-io/) + (Apache License, Version 2.0) * Apache Commons Lang:- org.apache.commons:commons-lang3:3.12.0 (https://commons.apache.org/proper/commons-lang/) + (Apache License, Version 2.0) * Apache Commons Text:- org.apache.commons:commons-text:1.9 (https://commons.apache.org/proper/commons-text) + (Apache License, Version 2.0) * Apache HttpClient:- org.apache.httpcomponents:httpclient:4.5.13 (http://hc.apache.org/httpcomponents-client) + (Apache License, Version 2.0) * Apache HttpCore:- org.apache.httpcomponents:httpcore:4.4.13 (http://hc.apache.org/httpcomponents-core-ga) + (Apache License, Version 2.0) * Apache Log4j API:- org.apache.logging.log4j:log4j-api:2.18.0 (https://logging.apache.org/log4j/2.x/log4j-api/) + (Apache License, Version 2.0) * Apache Log4j Core:- org.apache.logging.log4j:log4j-core:2.18.0 (https://logging.apache.org/log4j/2.x/log4j-core/) + (Apache License, Version 2.0) * Apache Log4j SLF4J Binding:- org.apache.logging.log4j:log4j-slf4j-impl:2.18.0 (https://logging.apache.org/log4j/2.x/log4j-slf4j-impl/) + (Apache License, Version 2.0) * Bean Validation API:- javax.validation:validation-api:1.1.0.Final (http://beanvalidation.org) + (Apache License, Version 2.0) * Byte Buddy (without dependencies):- net.bytebuddy:byte-buddy:1.12.1 (https://bytebuddy.net/byte-buddy) + (Apache License, Version 2.0) * Byte Buddy agent:- net.bytebuddy:byte-buddy-agent:1.12.1 (https://bytebuddy.net/byte-buddy-agent) + (Apache License, Version 2.0) * Commons Lang:- commons-lang:commons-lang:2.6 (http://commons.apache.org/lang/) + (Apache License, Version 2.0) * Commons Logging:- commons-logging:commons-logging:1.1.1 (http://commons.apache.org/logging) + (Apache License, Version 2.0) * Disruptor Framework:- com.lmax:disruptor:3.3.7 (http://lmax-exchange.github.com/disruptor) + (Apache License, Version 2.0) * FindBugs-jsr305:- com.google.code.findbugs:jsr305:3.0.1 (http://findbugs.sourceforge.net/) + (Apache License, Version 2.0) * Google Android Annotations Library:- com.google.android:annotations:4.1.1.4 (http://source.android.com/) + (Apache License, Version 2.0) * Gson:- com.google.code.gson:gson:2.8.6 (https://github.com/google/gson/gson) + (Apache License, Version 2.0) * Guava InternalFutureFailureAccess and InternalFutures:- com.google.guava:failureaccess:1.0.1 (https://github.com/google/guava/failureaccess) + (Apache License, Version 2.0) * Guava ListenableFuture only:- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava (https://github.com/google/guava/listenablefuture) + (Apache License, Version 2.0) * Guava: Google Core Libraries for Java:- com.google.guava:guava:30.0-jre (https://github.com/google/guava/guava) + (Apache License, Version 2.0) * J2ObjC Annotations:- com.google.j2objc:j2objc-annotations:1.3 (https://github.com/google/j2objc/) + (Apache License, Version 2.0) * Jackson module: Old JAXB Annotations (javax.xml.bind):- com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.14.0-rc1 (https://github.com/FasterXML/jackson-modules-base) + (Apache License, Version 2.0) * Jackson-JAXRS: JSON:- com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.14.0-rc1 (https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-json-provider) + (Apache License, Version 2.0) * Jackson-JAXRS: base:- com.fasterxml.jackson.jaxrs:jackson-jaxrs-base:2.14.0-rc1 (https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-base) + (Apache License, Version 2.0) * Jackson-annotations:- com.fasterxml.jackson.core:jackson-annotations:2.14.0-rc1 (https://github.com/FasterXML/jackson) + (Apache License, Version 2.0) * Jackson-core:- com.fasterxml.jackson.core:jackson-core:2.14.0-rc1 (https://github.com/FasterXML/jackson-core) + (Apache License, Version 2.0) * Jackson-dataformat-YAML:- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.3 (https://github.com/FasterXML/jackson-dataformats-text) + (Apache License, Version 2.0) * Joda-Time:- joda-time:joda-time:2.10.8 (https://www.joda.org/joda-time/) + (Apache License, Version 2.0) * Netty/All-in-One:- io.netty:netty-all:4.1.42.Final (https://netty.io/netty-all/) + (Apache License, Version 2.0) * Objenesis:- org.objenesis:objenesis:3.2 (http://objenesis.org/objenesis) + (Apache License, Version 2.0) * OpenTracing API:- io.opentracing:opentracing-api:0.22.0 (https://github.com/opentracing/opentracing-java/opentracing-api) + (Apache License, Version 2.0) * OpenTracing-mock:- io.opentracing:opentracing-mock:0.22.0 (https://github.com/opentracing/opentracing-java/opentracing-mock) + (Apache License, Version 2.0) * OpenTracing-noop:- io.opentracing:opentracing-noop:0.22.0 (https://github.com/opentracing/opentracing-java/opentracing-noop) + (Apache License, Version 2.0) * OpenTracing-util:- io.opentracing:opentracing-util:0.22.0 (https://github.com/opentracing/opentracing-java/opentracing-util) + (Apache License, Version 2.0) * SnakeYAML:- org.yaml:snakeyaml:1.18 (http://www.snakeyaml.org) + (Apache License, Version 2.0) * com.alipay.sofa.common:sofa-common-tools:- com.alipay.sofa.common:sofa-common-tools:1.0.12 (https://github.com/sofastack/sofa-common-tools) + (Apache License, Version 2.0) * com.alipay.sofa:bolt:- com.alipay.sofa:bolt:1.6.2 (https://github.com/alipay/sofa-bolt) + (Apache License, Version 2.0) * com.alipay.sofa:hessian:- com.alipay.sofa:hessian:3.3.7 (http://github.com/alipay/sofa-hessian) + (Apache License, Version 2.0) * com.alipay.sofa:sofa-rpc-all:- com.alipay.sofa:sofa-rpc-all:5.7.6 (http://github.com/sofastack/sofa-rpc) + (Apache License, Version 2.0) * error-prone annotations:- com.google.errorprone:error_prone_annotations:2.3.4 (http://nexus.sonatype.org/oss-repository-hosting.html/error_prone_parent/error_prone_annotations) + (Apache License, Version 2.0) * io.grpc:grpc-api:- io.grpc:grpc-api:1.28.0 (https://github.com/grpc/grpc-java) + (Apache License, Version 2.0) * io.grpc:grpc-context:- io.grpc:grpc-context:1.28.0 (https://github.com/grpc/grpc-java) + (Apache License, Version 2.0) * io.grpc:grpc-core:- io.grpc:grpc-core:1.28.0 (https://github.com/grpc/grpc-java) + (Apache License, Version 2.0) * io.grpc:grpc-netty-shaded:- io.grpc:grpc-netty-shaded:1.28.0 (https://github.com/grpc/grpc-java) + (Apache License, Version 2.0) * io.grpc:grpc-protobuf:- io.grpc:grpc-protobuf:1.28.0 (https://github.com/grpc/grpc-java) + (Apache License, Version 2.0) * io.grpc:grpc-protobuf-lite:- io.grpc:grpc-protobuf-lite:1.28.0 (https://github.com/grpc/grpc-java) + (Apache License, Version 2.0) * io.grpc:grpc-stub:- io.grpc:grpc-stub:1.28.0 (https://github.com/grpc/grpc-java) + (Apache License, Version 2.0) * jackson-databind:- com.fasterxml.jackson.core:jackson-databind:2.14.0-rc1 (https://github.com/FasterXML/jackson) + (Apache License, Version 2.0) * lookout-api:- com.alipay.sofa.lookout:lookout-api:1.4.1 (https://github.com/sofastack/sofa-lookout/lookout-api) + (Apache License, Version 2.0) * perfmark:perfmark-api:- io.perfmark:perfmark-api:0.19.0 (https://github.com/perfmark/perfmark) + (Apache License, Version 2.0) * proto-google-common-protos:- com.google.api.grpc:proto-google-common-protos:1.17.0 (https://github.com/googleapis/api-client-staging) + (Apache License, Version 2.0) * swagger-annotations:- io.swagger:swagger-annotations:1.5.18 (https://github.com/swagger-api/swagger-core/modules/swagger-annotations) + (Apache License, Version 2.0) * swagger-core:- io.swagger:swagger-core:1.5.18 (https://github.com/swagger-api/swagger-core/modules/swagger-core) + (Apache License, Version 2.0) * swagger-models:- io.swagger:swagger-models:1.5.18 (https://github.com/swagger-api/swagger-core/modules/swagger-models) + (Apache License, Version 2.0) * tracer-core:- com.alipay.sofa:tracer-core:3.0.8 (https://projects.spring.io/spring-boot/#/spring-boot-starter-parent/sofaboot-dependencies/tracer-all-parent/tracer-core) + (Apache License, Version 2.0) * OkHttp (com.squareup.okhttp3:okhttp:4.10.0 - https://github.com/square/okhttp) + (Apache License, Version 2.0) * OkHttp (com.squareup.okhttp3:logging-interceptor:4.10.0 - https://github.com/square/okhttp) + +======================================================================== +Third party CDDL licenses +======================================================================== + +The following components are provided under the CDDL License. +See licenses/ for text of these licenses. + (CDDL) * JavaBeans Activation Framework API jar:- javax.activation:javax.activation-api:1.2.0 (http://java.net/all/javax.activation-api/) + (CDDL 1.1) * jaxb-api:- javax.xml.bind:jaxb-api:2.3.1 (https://github.com/javaee/jaxb-spec/jaxb-api) + (Dual license consisting of the CDDL v1.1) * Default Provider:- org.glassfish:javax.json:1.0 (http://jsonp.java.net) + + +======================================================================== +Third party EPL licenses +======================================================================== + +The following components are provided under the EPL License. +See licenses/ for text of these licenses. + (Eclipse Public License - v2.0) * HK2 API module:- org.glassfish.hk2:hk2-api:3.0.1 (https://github.com/eclipse-ee4j/glassfish-hk2/hk2-api) + (Eclipse Public License - v2.0) * HK2 Implementation Utilities:- org.glassfish.hk2:hk2-utils:3.0.1 (https://github.com/eclipse-ee4j/glassfish-hk2/hk2-utils) + (Eclipse Public License - v2.0) * OSGi resource locator:- org.glassfish.hk2:osgi-resource-locator:1.0.3 (https://projects.eclipse.org/projects/ee4j/osgi-resource-locator) + (Eclipse Public License - v2.0) * ServiceLocator Default Implementation:- org.glassfish.hk2:hk2-locator:3.0.1 (https://github.com/eclipse-ee4j/glassfish-hk2/hk2-locator) + (Eclipse Public License - v2.0) * aopalliance version 1.0 repackaged as a module:- org.glassfish.hk2.external:aopalliance-repackaged:3.0.1 (https://github.com/eclipse-ee4j/glassfish-hk2/external/aopalliance-repackaged) + (Eclipse Public License - v2.0) * JUnit:- junit:junit:4.13.1 (http://junit.org) + +======================================================================== +Third party EDL licenses +======================================================================== + +The following components are provided under the EDL License. +See licenses/ for text of these licenses. + (Eclipse Distribution License - v1.0) * Jakarta Activation:- com.sun.activation:jakarta.activation:2.0.1 (https://github.com/eclipse-ee4j/jaf/jakarta.activation) + (Eclipse Distribution License - v1.0) * Jakarta Activation API jar:- jakarta.activation:jakarta.activation-api:1.2.2 (https://github.com/eclipse-ee4j/jaf/jakarta.activation-api) + (Eclipse Distribution License - v1.0) * Old JAXB Core:- com.sun.xml.bind:jaxb-core:3.0.2 (https://eclipse-ee4j.github.io/jaxb-ri/) + (Eclipse Distribution License - v1.0) * Old JAXB Runtime:- com.sun.xml.bind:jaxb-impl:3.0.2 (https://eclipse-ee4j.github.io/jaxb-ri/) + + +======================================================================== +Third party BSD licenses +======================================================================== + +The following components are provided under the BSD License. +See licenses/ for text of these licenses. + (The 3-Clause BSD License) * Hamcrest Core:- org.hamcrest:hamcrest-core:1.3 (https://github.com/hamcrest/JavaHamcrest/hamcrest-core) + (The 3-Clause BSD License) * Protocol Buffers [Core]:- com.google.protobuf:protobuf-java:3.11.0 (https://developers.google.com/protocol-buffers/protobuf-java/) + +======================================================================== +Third party MIT licenses +======================================================================== + +The following components are provided under the MIT License. +See licenses/ for text of these licenses. + (The MIT License)* Animal Sniffer Annotations:- org.codehaus.mojo:animal-sniffer-annotations:1.18 (http://www.mojohaus.org/animal-sniffer/animal-sniffer-annotations) + (The MIT License)* Checker Qual:- org.checkerframework:checker-qual:3.5.0 (https://checkerframework.org) + (The MIT License)* SLF4J API Module:- org.slf4j:slf4j-api:1.7.25 (http://www.slf4j.org) + (The MIT License)* mockito-core:- org.mockito:mockito-core:4.1.0 (https://github.com/mockito/mockito) diff --git a/hugegraph-commons/hugegraph-dist/release-docs/NOTICE b/hugegraph-commons/hugegraph-dist/release-docs/NOTICE new file mode 100644 index 0000000000..7d13a7d48f --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/NOTICE @@ -0,0 +1,935 @@ +Apache HugeGraph(incubating) +Copyright 2022-2023 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +The initial codebase was donated to the ASF by HugeGraph Authors, copyright 2017-2021. + +======================================================================== + +commons-logging NOTICE + +======================================================================== +// ------------------------------------------------------------------ +// NOTICE file corresponding to the section 4d of The Apache License, +// Version 2.0, in this case for Commons Logging +// ------------------------------------------------------------------ + +Commons Logging +Copyright 2001-2007 The Apache Software Foundation + +This product includes/uses software(s) developed by 'an unknown organization' + - Unnamed - avalon-framework:avalon-framework:jar:4.1.3 + - Unnamed - log4j:log4j:jar:1.2.12 + - Unnamed - logkit:logkit:jar:1.0.1 + + +======================================================================== + +httpclient NOTICE + +======================================================================== + +Apache HttpClient +Copyright 1999-2020 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + + +======================================================================== + +httpcore NOTICE + +======================================================================== + +Apache HttpCore +Copyright 2005-2020 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + + +======================================================================== + +jackson-core-2.14.0 NOTICE + +======================================================================== +# Jackson JSON processor + +Jackson is a high-performance, Free/Open Source JSON processing library. +It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has +been in development since 2007. +It is currently developed by a community of developers. + +## Licensing + +Jackson 2.x core and extension components are licensed under Apache License 2.0 +To find the details that apply to this artifact see the accompanying LICENSE file. + +## Credits + +A list of contributors may be found from CREDITS(-2.x) file, which is included +in some artifacts (usually source distributions); but is always available +from the source code management (SCM) system project uses. +======================================================================== + +jackson-databind-2.14.0 NOTICE + +======================================================================== +# Jackson JSON processor + +Jackson is a high-performance, Free/Open Source JSON processing library. +It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has +been in development since 2007. +It is currently developed by a community of developers. + +## Licensing + +Jackson 2.x core and extension components are licensed under Apache License 2.0 +To find the details that apply to this artifact see the accompanying LICENSE file. + +## Credits + +A list of contributors may be found from CREDITS(-2.x) file, which is included +in some artifacts (usually source distributions); but is always available +from the source code management (SCM) system project uses. +======================================================================== + +jackson-dataformat-yaml NOTICE + +======================================================================== +# Jackson JSON processor + +Jackson is a high-performance, Free/Open Source JSON processing library. +It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has +been in development since 2007. +It is currently developed by a community of developers, as well as supported +commercially by FasterXML.com. + +## Licensing + +Jackson core and extension components may be licensed under different licenses. +To find the details that apply to this artifact see the accompanying LICENSE file. +For more information, including possible other licensing options, contact +FasterXML.com (http://fasterxml.com). + +## Credits + +A list of contributors may be found from CREDITS file, which is included +in some artifacts (usually source distributions); but is always available +from the source code management (SCM) system project uses. +======================================================================== + +jackson-jaxrs-json-provider-2.14.0 NOTICE + +======================================================================== +# Jackson JSON processor + +Jackson is a high-performance, Free/Open Source JSON processing library. +It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has +been in development since 2007. +It is currently developed by a community of developers, as well as supported +commercially by FasterXML.com. + +## Licensing + +Jackson core and extension components may be licensed under different licenses. +To find the details that apply to this artifact see the accompanying LICENSE file. +For more information, including possible other licensing options, contact +FasterXML.com (http://fasterxml.com). + +## Credits + +A list of contributors may be found from CREDITS file, which is included +in some artifacts (usually source distributions); but is always available +from the source code management (SCM) system project uses. +======================================================================== + +jackson-module-jaxb-annotations-2.14.0 NOTICE + +======================================================================== +# Jackson JSON processor + +Jackson is a high-performance, Free/Open Source JSON processing library. +It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has +been in development since 2007. +It is currently developed by a community of developers, as well as supported +commercially by FasterXML.com. + +## Licensing + +Jackson core and extension components may licensed under different licenses. +To find the details that apply to this artifact see the accompanying LICENSE file. +For more information, including possible other licensing options, contact +FasterXML.com (http://fasterxml.com). + +## Credits + +A list of contributors may be found from CREDITS file, which is included +in some artifacts (usually source distributions); but is always available +from the source code management (SCM) system project uses. +======================================================================== + +log4j-api NOTICE + +======================================================================== + +Apache Log4j API +Copyright 1999-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + + +======================================================================== + +log4j-core NOTICE + +======================================================================== +Apache Log4j Core +Copyright 1999-2012 Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +ResolverUtil.java +Copyright 2005-2006 Tim Fennell + +======================================================================== + +log4j-slf4j-impl NOTICE + +======================================================================== + +Apache Log4j SLF4J Binding +Copyright 1999-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + + +======================================================================== + +gRPC NOTICE + +======================================================================== + + +Copyright 2014 The gRPC Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------------------------------------------------------------------- + +This product contains a modified portion of 'OkHttp', an open source +HTTP & SPDY client for Android and Java applications, which can be obtained +at: + + * LICENSE: + * okhttp/third_party/okhttp/LICENSE (Apache License 2.0) + * HOMEPAGE: + * https://github.com/square/okhttp + * LOCATION_IN_GRPC: + * okhttp/third_party/okhttp + +This product contains a modified portion of 'Envoy', an open source +cloud-native high-performance edge/middle/service proxy, which can be +obtained at: + + * LICENSE: + * xds/third_party/envoy/LICENSE (Apache License 2.0) + * NOTICE: + * xds/third_party/envoy/NOTICE + * HOMEPAGE: + * https://www.envoyproxy.io + * LOCATION_IN_GRPC: + * xds/third_party/envoy + +This product contains a modified portion of 'protoc-gen-validate (PGV)', +an open source protoc plugin to generate polyglot message validators, +which can be obtained at: + + * LICENSE: + * xds/third_party/protoc-gen-validate/LICENSE (Apache License 2.0) + * NOTICE: + * xds/third_party/protoc-gen-validate/NOTICE + * HOMEPAGE: + * https://github.com/envoyproxy/protoc-gen-validate + * LOCATION_IN_GRPC: + * xds/third_party/protoc-gen-validate + +This product contains a modified portion of 'udpa', +an open source universal data plane API, which can be obtained at: + + * LICENSE: + * xds/third_party/udpa/LICENSE (Apache License 2.0) + * HOMEPAGE: + * https://github.com/cncf/udpa + * LOCATION_IN_GRPC: + * xds/third_party/udpa + +======================================================================== + +jaxb-ri NOTICE + +======================================================================== +# Notices for Eclipse Implementation of JAXB + +This content is produced and maintained by the Eclipse Implementation of JAXB +project. + +* Project home: https://projects.eclipse.org/projects/ee4j.jaxb-impl + +## Trademarks + +Eclipse Implementation of JAXB is a trademark of the Eclipse Foundation. + +## Copyright + +All content is the property of the respective authors or their employers. For +more information regarding authorship of content, please consult the listed +source code repository logs. + +## Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Eclipse Distribution License v. 1.0 which is available at +http://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: BSD-3-Clause + +## Source Code + +The project maintains the following source code repositories: + +* https://github.com/eclipse-ee4j/jaxb-ri +* https://github.com/eclipse-ee4j/jaxb-istack-commons +* https://github.com/eclipse-ee4j/jaxb-dtd-parser +* https://github.com/eclipse-ee4j/jaxb-fi +* https://github.com/eclipse-ee4j/jaxb-stax-ex +* https://github.com/eclipse-ee4j/jax-rpc-ri + +## Third-party Content + +This project leverages the following third party content. + +Apache Ant (1.10.2) + +* License: Apache-2.0 AND W3C AND LicenseRef-Public-Domain + +Apache Ant (1.10.2) + +* License: Apache-2.0 AND W3C AND LicenseRef-Public-Domain + +Apache Felix (1.2.0) + +* License: Apache License, 2.0 + +args4j (2.33) + +* License: MIT License + +dom4j (1.6.1) + +* License: Custom license based on Apache 1.1 + +file-management (3.0.0) + +* License: Apache-2.0 +* Project: https://maven.apache.org/shared/file-management/ +* Source: + https://svn.apache.org/viewvc/maven/shared/tags/file-management-3.0.0/ + +JUnit (4.12) + +* License: Eclipse Public License + +JUnit (4.12) + +* License: Eclipse Public License + +maven-compat (3.5.2) + +* License: Apache-2.0 +* Project: https://maven.apache.org/ref/3.5.2/maven-compat/ +* Source: + https://mvnrepository.com/artifact/org.apache.maven/maven-compat/3.5.2 + +maven-core (3.5.2) + +* License: Apache-2.0 +* Project: https://maven.apache.org/ref/3.5.2/maven-core/index.html +* Source: https://mvnrepository.com/artifact/org.apache.maven/maven-core/3.5.2 + +maven-plugin-annotations (3.5) + +* License: Apache-2.0 +* Project: https://maven.apache.org/plugin-tools/maven-plugin-annotations/ +* Source: + https://github.com/apache/maven-plugin-tools/tree/master/maven-plugin-annotations + +maven-plugin-api (3.5.2) + +* License: Apache-2.0 + +maven-resolver-api (1.1.1) + +* License: Apache-2.0 + +maven-resolver-api (1.1.1) + +* License: Apache-2.0 + +maven-resolver-connector-basic (1.1.1) + +* License: Apache-2.0 + +maven-resolver-impl (1.1.1) + +* License: Apache-2.0 + +maven-resolver-spi (1.1.1) + +* License: Apache-2.0 + +maven-resolver-transport-file (1.1.1) + +* License: Apache-2.0 +* Project: https://maven.apache.org/resolver/maven-resolver-transport-file/ +* Source: + https://github.com/apache/maven-resolver/tree/master/maven-resolver-transport-file + +maven-resolver-util (1.1.1) + +* License: Apache-2.0 + +maven-settings (3.5.2) + +* License: Apache-2.0 +* Source: + https://mvnrepository.com/artifact/org.apache.maven/maven-settings/3.5.2 + +OSGi Service Platform Core Companion Code (6.0) + +* License: Apache License, 2.0 + +plexus-archiver (3.5) + +* License: Apache-2.0 +* Project: https://codehaus-plexus.github.io/plexus-archiver/ +* Source: https://github.com/codehaus-plexus/plexus-archiver + +plexus-io (3.0.0) + +* License: Apache-2.0 + +plexus-utils (3.1.0) + +* License: Apache- 2.0 or Apache- 1.1 or BSD or Public Domain or Indiana + University Extreme! Lab Software License V1.1.1 (Apache 1.1 style) + +relaxng-datatype (1.0) + +* License: New BSD license + +Sax (0.2) + +* License: SAX-PD +* Project: http://www.megginson.com/downloads/SAX/ +* Source: http://sourceforge.net/project/showfiles.php?group_id=29449 + +testng (6.14.2) + +* License: Apache-2.0 AND (MIT ) +* Project: https://testng.org/doc/index.html +* Source: https://github.com/cbeust/testng + +wagon-http-lightweight (3.0.0) + +* License: Pending +* Project: https://maven.apache.org/wagon/ +* Source: + https://mvnrepository.com/artifact/org.apache.maven.wagon/wagon-http-lightweight/3.0.0 + +xz for java (1.8) + +* License: LicenseRef-Public-Domain + +## Cryptography + +Content may contain encryption software. The country in which you are currently +may have restrictions on the import, possession, and use, and/or re-export to +another country, of encryption software. BEFORE using any encryption software, +please check the country's laws, regulations and policies concerning the import, +possession, or use, and re-export of encryption software, to see if this is +permitted. + + +======================================================================== + +Swagger Core NOTICE + +======================================================================== +Swagger Core - ${pom.name} +Copyright (c) 2015. SmartBear Software Inc. +Swagger Core - ${pom.name} is licensed under Apache 2.0 license. +Copy of the Apache 2.0 license can be found in `LICENSE` file. + + +======================================================================== + +Joda time NOTICE + +======================================================================== + +============================================================================= += NOTICE file corresponding to section 4d of the Apache License Version 2.0 = +============================================================================= +This product includes software developed by +Joda.org (https://www.joda.org/). + +======================================================================== + +Eclipse GlassFish NOTICE + +======================================================================== + +# Notices for Eclipse GlassFish + +This content is produced and maintained by the Eclipse GlassFish project. + +* Project home: https://projects.eclipse.org/projects/ee4j.glassfish + +## Trademarks + +Eclipse GlassFish, and GlassFish are trademarks of the Eclipse Foundation. + +## Copyright + +All content is the property of the respective authors or their employers. For +more information regarding authorship of content, please consult the listed +source code repository logs. + +## Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Eclipse Public License v. 2.0 which is available at +http://www.eclipse.org/legal/epl-2.0. This Source Code may also be made +available under the following Secondary Licenses when the conditions for such +availability set forth in the Eclipse Public License v. 2.0 are satisfied: GNU +General Public License, version 2 with the GNU Classpath Exception which is +available at https://www.gnu.org/software/classpath/license.html. + +SPDX-License-Identifier: EPL-2.0 + +## Source Code + +The project maintains the following source code repositories: + +* https://github.com/eclipse-ee4j/glassfish-ha-api +* https://github.com/eclipse-ee4j/glassfish-logging-annotation-processor +* https://github.com/eclipse-ee4j/glassfish-shoal +* https://github.com/eclipse-ee4j/glassfish-cdi-porting-tck +* https://github.com/eclipse-ee4j/glassfish-jsftemplating +* https://github.com/eclipse-ee4j/glassfish-hk2-extra +* https://github.com/eclipse-ee4j/glassfish-hk2 +* https://github.com/eclipse-ee4j/glassfish-fighterfish + +## Third-party Content + +This project leverages the following third party content. + +None + +## Cryptography + +Content may contain encryption software. The country in which you are currently +may have restrictions on the import, possession, and use, and/or re-export to +another country, of encryption software. BEFORE using any encryption software, +please check the country's laws, regulations and policies concerning the import, +possession, or use, and re-export of encryption software, to see if this is +permitted. + + +======================================================================== + +netty NOTICE + +======================================================================== + + The Netty Project + ================= + +Please visit the Netty web site for more information: + + * https://netty.io/ + +Copyright 2014 The Netty Project + +The Netty Project 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: + + https://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. + +Also, please refer to each LICENSE..txt file, which is located in +the 'license' directory of the distribution file, for the license terms of the +components that this product depends on. + +------------------------------------------------------------------------------- +This product contains the extensions to Java Collections Framework which has +been derived from the works by JSR-166 EG, Doug Lea, and Jason T. Greene: + + * LICENSE: + * license/LICENSE.jsr166y.txt (Public Domain) + * HOMEPAGE: + * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/ + * http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbosscache/experimental/jsr166/ + +This product contains a modified version of Robert Harder's Public Domain +Base64 Encoder and Decoder, which can be obtained at: + + * LICENSE: + * license/LICENSE.base64.txt (Public Domain) + * HOMEPAGE: + * http://iharder.sourceforge.net/current/java/base64/ + +This product contains a modified portion of 'Webbit', an event based +WebSocket and HTTP server, which can be obtained at: + + * LICENSE: + * license/LICENSE.webbit.txt (BSD License) + * HOMEPAGE: + * https://github.com/joewalnes/webbit + +This product contains a modified portion of 'SLF4J', a simple logging +facade for Java, which can be obtained at: + + * LICENSE: + * license/LICENSE.slf4j.txt (MIT License) + * HOMEPAGE: + * https://www.slf4j.org/ + +This product contains a modified portion of 'Apache Harmony', an open source +Java SE, which can be obtained at: + + * NOTICE: + * license/NOTICE.harmony.txt + * LICENSE: + * license/LICENSE.harmony.txt (Apache License 2.0) + * HOMEPAGE: + * https://archive.apache.org/dist/harmony/ + +This product contains a modified portion of 'jbzip2', a Java bzip2 compression +and decompression library written by Matthew J. Francis. It can be obtained at: + + * LICENSE: + * license/LICENSE.jbzip2.txt (MIT License) + * HOMEPAGE: + * https://code.google.com/p/jbzip2/ + +This product contains a modified portion of 'libdivsufsort', a C API library to construct +the suffix array and the Burrows-Wheeler transformed string for any input string of +a constant-size alphabet written by Yuta Mori. It can be obtained at: + + * LICENSE: + * license/LICENSE.libdivsufsort.txt (MIT License) + * HOMEPAGE: + * https://github.com/y-256/libdivsufsort + +This product contains a modified portion of Nitsan Wakart's 'JCTools', Java Concurrency Tools for the JVM, + which can be obtained at: + + * LICENSE: + * license/LICENSE.jctools.txt (ASL2 License) + * HOMEPAGE: + * https://github.com/JCTools/JCTools + +This product optionally depends on 'JZlib', a re-implementation of zlib in +pure Java, which can be obtained at: + + * LICENSE: + * license/LICENSE.jzlib.txt (BSD style License) + * HOMEPAGE: + * http://www.jcraft.com/jzlib/ + +This product optionally depends on 'Compress-LZF', a Java library for encoding and +decoding data in LZF format, written by Tatu Saloranta. It can be obtained at: + + * LICENSE: + * license/LICENSE.compress-lzf.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/ning/compress + +This product optionally depends on 'lz4', a LZ4 Java compression +and decompression library written by Adrien Grand. It can be obtained at: + + * LICENSE: + * license/LICENSE.lz4.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/jpountz/lz4-java + +This product optionally depends on 'lzma-java', a LZMA Java compression +and decompression library, which can be obtained at: + + * LICENSE: + * license/LICENSE.lzma-java.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/jponge/lzma-java + +This product optionally depends on 'zstd-jni', a zstd-jni Java compression +and decompression library, which can be obtained at: + + * LICENSE: + * license/LICENSE.zstd-jni.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/luben/zstd-jni + +This product contains a modified portion of 'jfastlz', a Java port of FastLZ compression +and decompression library written by William Kinney. It can be obtained at: + + * LICENSE: + * license/LICENSE.jfastlz.txt (MIT License) + * HOMEPAGE: + * https://code.google.com/p/jfastlz/ + +This product contains a modified portion of and optionally depends on 'Protocol Buffers', Google's data +interchange format, which can be obtained at: + + * LICENSE: + * license/LICENSE.protobuf.txt (New BSD License) + * HOMEPAGE: + * https://github.com/google/protobuf + +This product optionally depends on 'Bouncy Castle Crypto APIs' to generate +a temporary self-signed X.509 certificate when the JVM does not provide the +equivalent functionality. It can be obtained at: + + * LICENSE: + * license/LICENSE.bouncycastle.txt (MIT License) + * HOMEPAGE: + * https://www.bouncycastle.org/ + +This product optionally depends on 'Snappy', a compression library produced +by Google Inc, which can be obtained at: + + * LICENSE: + * license/LICENSE.snappy.txt (New BSD License) + * HOMEPAGE: + * https://github.com/google/snappy + +This product optionally depends on 'JBoss Marshalling', an alternative Java +serialization API, which can be obtained at: + + * LICENSE: + * license/LICENSE.jboss-marshalling.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/jboss-remoting/jboss-marshalling + +This product optionally depends on 'Caliper', Google's micro- +benchmarking framework, which can be obtained at: + + * LICENSE: + * license/LICENSE.caliper.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/google/caliper + +This product optionally depends on 'Apache Commons Logging', a logging +framework, which can be obtained at: + + * LICENSE: + * license/LICENSE.commons-logging.txt (Apache License 2.0) + * HOMEPAGE: + * https://commons.apache.org/logging/ + +This product optionally depends on 'Apache Log4J', a logging framework, which +can be obtained at: + + * LICENSE: + * license/LICENSE.log4j.txt (Apache License 2.0) + * HOMEPAGE: + * https://logging.apache.org/log4j/ + +This product optionally depends on 'Aalto XML', an ultra-high performance +non-blocking XML processor, which can be obtained at: + + * LICENSE: + * license/LICENSE.aalto-xml.txt (Apache License 2.0) + * HOMEPAGE: + * https://wiki.fasterxml.com/AaltoHome + +This product contains a modified version of 'HPACK', a Java implementation of +the HTTP/2 HPACK algorithm written by Twitter. It can be obtained at: + + * LICENSE: + * license/LICENSE.hpack.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/twitter/hpack + +This product contains a modified version of 'HPACK', a Java implementation of +the HTTP/2 HPACK algorithm written by Cory Benfield. It can be obtained at: + + * LICENSE: + * license/LICENSE.hyper-hpack.txt (MIT License) + * HOMEPAGE: + * https://github.com/python-hyper/hpack/ + +This product contains a modified version of 'HPACK', a Java implementation of +the HTTP/2 HPACK algorithm written by Tatsuhiro Tsujikawa. It can be obtained at: + + * LICENSE: + * license/LICENSE.nghttp2-hpack.txt (MIT License) + * HOMEPAGE: + * https://github.com/nghttp2/nghttp2/ + +This product contains a modified portion of 'Apache Commons Lang', a Java library +provides utilities for the java.lang API, which can be obtained at: + + * LICENSE: + * license/LICENSE.commons-lang.txt (Apache License 2.0) + * HOMEPAGE: + * https://commons.apache.org/proper/commons-lang/ + + +This product contains the Maven wrapper scripts from 'Maven Wrapper', that provides an easy way to ensure a user has everything necessary to run the Maven build. + + * LICENSE: + * license/LICENSE.mvn-wrapper.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/takari/maven-wrapper + +This product contains the dnsinfo.h header file, that provides a way to retrieve the system DNS configuration on MacOS. +This private header is also used by Apple's open source + mDNSResponder (https://opensource.apple.com/tarballs/mDNSResponder/). + + * LICENSE: + * license/LICENSE.dnsinfo.txt (Apple Public Source License 2.0) + * HOMEPAGE: + * https://www.opensource.apple.com/source/configd/configd-453.19/dnsinfo/dnsinfo.h + +This product optionally depends on 'Brotli4j', Brotli compression and +decompression for Java., which can be obtained at: + + * LICENSE: + * license/LICENSE.brotli4j.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/hyperxpro/Brotli4j +======================================================================== + +perfmark NOTICE + +======================================================================== + +Copyright 2019 Google LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------------------------------------------------------------------- + +This product contains a modified portion of 'Catapult', an open source +Trace Event viewer for Chome, Linux, and Android applications, which can +be obtained at: + + * LICENSE: + * traceviewer/src/main/resources/io/perfmark/traceviewer/third_party/catapult/LICENSE (New BSD License) + * HOMEPAGE: + * https://github.com/catapult-project/catapult + +This product contains a modified portion of 'Polymer', a library for Web +Components, which can be obtained at: + * LICENSE: + * traceviewer/src/main/resources/io/perfmark/traceviewer/third_party/polymer/LICENSE (New BSD License) + * HOMEPAGE: + * https://github.com/Polymer/polymer + + +This product contains a modified portion of 'ASM', an open source +Java Bytecode library, which can be obtained at: + + * LICENSE: + * agent/src/main/resources/io/perfmark/agent/third_party/asm/LICENSE (BSD style License) + * HOMEPAGE: + * https://asm.ow2.io/ +======================================================================== + +junit5 NOTICE + +======================================================================== +Open Source Licenses +==================== + +This product may include a number of subcomponents with separate +copyright notices and license terms. Your use of the source code for +these subcomponents is subject to the terms and conditions of the +subcomponent's license, as noted in the LICENSE-.md +files. +======================================================================== + +jaf-api NOTICE + +======================================================================== + +# Notices for Jakarta Activation + +This content is produced and maintained by Jakarta Activation project. + +* Project home: https://projects.eclipse.org/projects/ee4j.jaf + +## Copyright + +All content is the property of the respective authors or their employers. For +more information regarding authorship of content, please consult the listed +source code repository logs. + +## Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Eclipse Distribution License v. 1.0, +which is available at http://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: BSD-3-Clause + +## Source Code + +The project maintains the following source code repositories: + +* https://github.com/eclipse-ee4j/jaf +======================================================================== + +okhttp NOTICE + +======================================================================== + +Note that publicsuffixes.gz is compiled from The Public Suffix List: +https://publicsuffix.org/list/public_suffix_list.dat + +It is subject to the terms of the Mozilla Public License, v. 2.0: +https://mozilla.org/MPL/2.0/ diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-JavaHamcrest.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-JavaHamcrest.txt new file mode 100644 index 0000000000..4933bda5ba --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-JavaHamcrest.txt @@ -0,0 +1,27 @@ +BSD License + +Copyright (c) 2000-2015 www.hamcrest.org +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of +conditions and the following disclaimer. Redistributions in binary form must reproduce +the above copyright notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the distribution. + +Neither the name of Hamcrest nor the names of its contributors may be used to endorse +or promote products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY +WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-animal-sniffer.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-animal-sniffer.txt new file mode 100644 index 0000000000..370fb559bb --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-animal-sniffer.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2009 codehaus.org. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-aopalliance-repackaged.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-aopalliance-repackaged.txt new file mode 100644 index 0000000000..4a00ba9482 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-aopalliance-repackaged.txt @@ -0,0 +1,362 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1 + +1. Definitions. + + 1.1. "Contributor" means each individual or entity that creates or + contributes to the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Software, prior Modifications used by a Contributor (if any), and + the Modifications made by that particular Contributor. + + 1.3. "Covered Software" means (a) the Original Software, or (b) + Modifications, or (c) the combination of files containing Original + Software with files containing Modifications, in each case including + portions thereof. + + 1.4. "Executable" means the Covered Software in any form other than + Source Code. + + 1.5. "Initial Developer" means the individual or entity that first + makes Original Software available under this License. + + 1.6. "Larger Work" means a work which combines Covered Software or + portions thereof with code not governed by the terms of this License. + + 1.7. "License" means this document. + + 1.8. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means the Source Code and Executable form of + any of the following: + + A. Any file that results from an addition to, deletion from or + modification of the contents of a file containing Original Software + or previous Modifications; + + B. Any new file that contains any part of the Original Software or + previous Modification; or + + C. Any new file that is contributed or otherwise made available + under the terms of this License. + + 1.10. "Original Software" means the Source Code and Executable form + of computer software code that is originally released under this + License. + + 1.11. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.12. "Source Code" means (a) the common form of computer software + code in which modifications are made and (b) associated + documentation included in or with such code. + + 1.13. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, + this License. For legal entities, "You" includes any entity which + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject + to third party intellectual property claims, the Initial Developer + hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer, to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Software (or portions thereof), with or without Modifications, + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of + Original Software, to make, have made, use, practice, sell, and + offer for sale, and/or otherwise dispose of the Original Software + (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on + the date Initial Developer first distributes or otherwise makes the + Original Software available to a third party under the terms of this + License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: (1) for code that You delete from the Original Software, or + (2) for infringements caused by: (i) the modification of the + Original Software, or (ii) the combination of the Original Software + with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject + to third party intellectual property claims, each Contributor hereby + grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof), either on an + unmodified basis, with other Modifications, as Covered Software + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling + of Modifications made by that Contributor either alone and/or in + combination with its Contributor Version (or portions of such + combination), to make, use, sell, offer for sale, have made, and/or + otherwise dispose of: (1) Modifications made by that Contributor (or + portions thereof); and (2) the combination of Modifications made by + that Contributor with its Contributor Version (or portions of such + combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective + on the date Contributor first distributes or otherwise makes the + Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: (1) for any code that Contributor has deleted from the + Contributor Version; (2) for infringements caused by: (i) third + party modifications of Contributor Version, or (ii) the combination + of Modifications made by that Contributor with other software + (except as part of the Contributor Version) or other devices; or (3) + under Patent Claims infringed by Covered Software in the absence of + Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make available + in Executable form must also be made available in Source Code form + and that Source Code form must be distributed only under the terms + of this License. You must include a copy of this License with every + copy of the Source Code form of the Covered Software You distribute + or otherwise make available. You must inform recipients of any such + Covered Software in Executable form as to how they can obtain such + Covered Software in Source Code form in a reasonable manner on or + through a medium customarily used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are + governed by the terms of this License. You represent that You + believe Your Modifications are Your original creation(s) and/or You + have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that + identifies You as the Contributor of the Modification. You may not + remove or alter any copyright, patent or trademark notices contained + within the Covered Software, or any notices of licensing or any + descriptive text giving attribution to any Contributor or the + Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in + Source Code form that alters or restricts the applicable version of + this License or the recipients' rights hereunder. You may choose to + offer, and to charge a fee for, warranty, support, indemnity or + liability obligations to one or more recipients of Covered Software. + However, you may do so only on Your own behalf, and not on behalf of + the Initial Developer or any Contributor. You must make it + absolutely clear that any such warranty, support, indemnity or + liability obligation is offered by You alone, and You hereby agree + to indemnify the Initial Developer and every Contributor for any + liability incurred by the Initial Developer or such Contributor as a + result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software under + the terms of this License or under the terms of a license of Your + choice, which may contain terms different from this License, + provided that You are in compliance with the terms of this License + and that the license for the Executable form does not attempt to + limit or alter the recipient's rights in the Source Code form from + the rights set forth in this License. If You distribute the Covered + Software in Executable form under a different license, You must make + it absolutely clear that any terms which differ from this License + are offered by You alone, not by the Initial Developer or + Contributor. You hereby agree to indemnify the Initial Developer and + every Contributor for any liability incurred by the Initial + Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with + other code not governed by the terms of this License and distribute + the Larger Work as a single product. In such a case, You must make + sure the requirements of this License are fulfilled for the Covered + Software. + +4. Versions of the License. + + 4.1. New Versions. + + Oracle is the initial license steward and may publish revised and/or + new versions of this License from time to time. Each version will be + given a distinguishing version number. Except as provided in Section + 4.3, no one other than the license steward has the right to modify + this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the + Covered Software available under the terms of the version of the + License under which You originally received the Covered Software. If + the Initial Developer includes a notice in the Original Software + prohibiting it from being distributed or otherwise made available + under any subsequent version of the License, You must distribute and + make the Covered Software available under the terms of the version + of the License under which You originally received the Covered + Software. Otherwise, You may also choose to use, distribute or + otherwise make the Covered Software available under the terms of any + subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new + license for Your Original Software, You may create and use a + modified version of this License if You: (a) rename the license and + remove any references to the name of the license steward (except to + note that the license differs from this License); and (b) otherwise + make it clear that the license contains terms which differ from this + License. + +5. DISCLAIMER OF WARRANTY. + + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE + IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR + NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF + THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE + DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY + OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, + REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS + AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to + cure such breach within 30 days of becoming aware of the breach. + Provisions which, by their nature, must remain in effect beyond the + termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding + declaratory judgment actions) against Initial Developer or a + Contributor (the Initial Developer or Contributor against whom You + assert such claim is referred to as "Participant") alleging that the + Participant Software (meaning the Contributor Version where the + Participant is a Contributor or the Original Software where the + Participant is the Initial Developer) directly or indirectly + infringes any patent, then any and all rights granted directly or + indirectly to You by such Participant, the Initial Developer (if the + Initial Developer is not the Participant) and all Contributors under + Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice + from Participant terminate prospectively and automatically at the + expiration of such 60 day notice period, unless if within such 60 + day period You withdraw Your claim with respect to the Participant + Software against such Participant either unilaterally or pursuant to + a written agreement with Participant. + + 6.3. If You assert a patent infringement claim against Participant + alleging that the Participant Software directly or indirectly + infringes any patent where such claim is resolved (such as by + license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 6.4. In the event of termination under Sections 6.1 or 6.2 above, + all end user licenses that have been validly granted by You or any + distributor hereunder prior to termination (excluding licenses + granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF + COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE + TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER + FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR + LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE + POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT + APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH + PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH + LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR + LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION + AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + + The Covered Software is a "commercial item," as that term is defined + in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" (as that term is defined at 48 C.F.R. § + 252.227-7014(a)(1)) and "commercial computer software documentation" + as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent + with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 + (June 1995), all U.S. Government End Users acquire Covered Software + with only those rights set forth herein. This U.S. Government Rights + clause is in lieu of, and supersedes, any other FAR, DFAR, or other + clause or provision that addresses Government rights in computer + software under this License. + +9. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + the law of the jurisdiction specified in a notice contained within + the Original Software (except to the extent applicable law, if any, + provides otherwise), excluding such jurisdiction's conflict-of-law + provisions. Any litigation relating to this License shall be subject + to the jurisdiction of the courts located in the jurisdiction and + venue specified in a notice contained within the Original Software, + with the losing party responsible for costs, including, without + limitation, court costs and reasonable attorneys' fees and expenses. + The application of the United Nations Convention on Contracts for + the International Sale of Goods is expressly excluded. Any law or + regulation which provides that the language of a contract shall be + construed against the drafter shall not apply to this License. You + agree that You alone are responsible for compliance with the United + States export administration regulations (and the export control + laws and regulation of any other countries) when You use, distribute + or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +------------------------------------------------------------------------ + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION +LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the +State of California (excluding conflict-of-law provisions). Any +litigation relating to this License shall be subject to the jurisdiction +of the Federal Courts of the Northern District of California and the +state courts of the State of California, with venue lying in Santa Clara +County, California. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-api-client-staging.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-api-client-staging.txt new file mode 100644 index 0000000000..97ee06a0a4 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-api-client-staging.txt @@ -0,0 +1,25 @@ +Copyright 2016, Google Inc. +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-checker-qual.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-checker-qual.txt new file mode 100644 index 0000000000..9837c6b69f --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-checker-qual.txt @@ -0,0 +1,22 @@ +Checker Framework qualifiers +Copyright 2004-present by the Checker Framework developers + +MIT License: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-beanutils.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-beanutils.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-beanutils.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-codec.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-codec.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-codec.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-collections.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-collections.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-collections.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-configuration.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-configuration.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-configuration.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-configuration2.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-configuration2.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-configuration2.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-io.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-io.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-io.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-lang.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-lang.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-lang.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-lang3.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-lang3.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-lang3.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-logging.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-logging.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-logging.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-text.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-text.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-commons-text.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-failureaccess.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-failureaccess.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-failureaccess.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-glassfish-hk2.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-glassfish-hk2.txt new file mode 100644 index 0000000000..bda7db00c5 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-glassfish-hk2.txt @@ -0,0 +1,277 @@ +# Eclipse Public License - v 2.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + + 1. DEFINITIONS + + "Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + + "Contributor" means any person or entity that Distributes the Program. + + "Licensed Patents" mean patent claims licensable by a Contributor which + are necessarily infringed by the use or sale of its Contribution alone + or when combined with the Program. + + "Program" means the Contributions Distributed in accordance with this + Agreement. + + "Recipient" means anyone who receives the Program under this Agreement + or any Secondary License (as applicable), including Contributors. + + "Derivative Works" shall mean any work, whether in Source Code or other + form, that is based on (or derived from) the Program and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. + + "Modified Works" shall mean any work in Source Code or other form that + results from an addition to, deletion from, or modification of the + contents of the Program, including, for purposes of clarity any new file + in Source Code form that contains any contents of the Program. Modified + Works shall not include works that contain only declarations, + interfaces, types, classes, structures, or files of the Program solely + in each case in order to link to, bind by name, or subclass the Program + or Modified Works thereof. + + "Distribute" means the acts of a) distributing or b) making available + in any manner that enables the transfer of a copy. + + "Source Code" means the form of a Program preferred for making + modifications, including but not limited to software source code, + documentation source, and configuration files. + + "Secondary License" means either the GNU General Public License, + Version 2.0, or any later versions of that license, including any + exceptions or additional permissions as identified by the initial + Contributor. + + 2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + + 3. REQUIREMENTS + + 3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + + 3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + + 3.3 Contributors may not remove or alter any copyright, patent, + trademark, attribution notices, disclaimers of warranty, or limitations + of liability ("notices") contained within the Program from any copy of + the Program which they Distribute, provided that Contributors may add + their own appropriate notices. + + 4. COMMERCIAL DISTRIBUTION + + Commercial distributors of software may accept certain responsibilities + with respect to end users, business partners and the like. While this + license is intended to facilitate the commercial use of the Program, + the Contributor who includes the Program in a commercial product + offering should do so in a manner which does not create potential + liability for other Contributors. Therefore, if a Contributor includes + the Program in a commercial product offering, such Contributor + ("Commercial Contributor") hereby agrees to defend and indemnify every + other Contributor ("Indemnified Contributor") against any losses, + damages and costs (collectively "Losses") arising from claims, lawsuits + and other legal actions brought by a third party against the Indemnified + Contributor to the extent caused by the acts or omissions of such + Commercial Contributor in connection with its distribution of the Program + in a commercial product offering. The obligations in this section do not + apply to any claims or Losses relating to any actual or alleged + intellectual property infringement. In order to qualify, an Indemnified + Contributor must: a) promptly notify the Commercial Contributor in + writing of such claim, and b) allow the Commercial Contributor to control, + and cooperate with the Commercial Contributor in, the defense and any + related settlement negotiations. The Indemnified Contributor may + participate in any such claim at its own expense. + + For example, a Contributor might include the Program in a commercial + product offering, Product X. That Contributor is then a Commercial + Contributor. If that Commercial Contributor then makes performance + claims, or offers warranties related to Product X, those performance + claims and warranties are such Commercial Contributor's responsibility + alone. Under this section, the Commercial Contributor would have to + defend claims against the other Contributors related to those performance + claims and warranties, and if a court requires any other Contributor to + pay any damages as a result, the Commercial Contributor must pay + those damages. + + 5. NO WARRANTY + + EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT + PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" + BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR + IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF + TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR + PURPOSE. Each Recipient is solely responsible for determining the + appropriateness of using and distributing the Program and assumes all + risks associated with its exercise of rights under this Agreement, + including but not limited to the risks and costs of program errors, + compliance with applicable laws, damage to or loss of data, programs + or equipment, and unavailability or interruption of operations. + + 6. DISCLAIMER OF LIABILITY + + EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT + PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS + SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST + PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE + EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + + 7. GENERAL + + If any provision of this Agreement is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of + the remainder of the terms of this Agreement, and without further + action by the parties hereto, such provision shall be reformed to the + minimum extent necessary to make such provision valid and enforceable. + + If Recipient institutes patent litigation against any entity + (including a cross-claim or counterclaim in a lawsuit) alleging that the + Program itself (excluding combinations of the Program with other software + or hardware) infringes such Recipient's patent(s), then such Recipient's + rights granted under Section 2(b) shall terminate as of the date such + litigation is filed. + + All Recipient's rights under this Agreement shall terminate if it + fails to comply with any of the material terms or conditions of this + Agreement and does not cure such failure in a reasonable period of + time after becoming aware of such noncompliance. If all Recipient's + rights under this Agreement terminate, Recipient agrees to cease use + and distribution of the Program as soon as reasonably practicable. + However, Recipient's obligations under this Agreement and any licenses + granted by Recipient relating to the Program shall continue and survive. + + Everyone is permitted to copy and distribute copies of this Agreement, + but in order to avoid inconsistency the Agreement is copyrighted and + may only be modified in the following manner. The Agreement Steward + reserves the right to publish new versions (including revisions) of + this Agreement from time to time. No one other than the Agreement + Steward has the right to modify this Agreement. The Eclipse Foundation + is the initial Agreement Steward. The Eclipse Foundation may assign the + responsibility to serve as the Agreement Steward to a suitable separate + entity. Each new version of the Agreement will be given a distinguishing + version number. The Program (including Contributions) may always be + Distributed subject to the version of the Agreement under which it was + received. In addition, after a new version of the Agreement is published, + Contributor may elect to Distribute the Program (including its + Contributions) under the new version. + + Except as expressly stated in Sections 2(a) and 2(b) above, Recipient + receives no rights or licenses to the intellectual property of any + Contributor under this Agreement, whether expressly, by implication, + estoppel or otherwise. All rights in the Program not expressly granted + under this Agreement are reserved. Nothing in this Agreement is intended + to be enforceable by any entity that is not a Contributor or Recipient. + No third-party beneficiary rights are created under this Agreement. + + Exhibit A - Form of Secondary Licenses Notice + + "This Source Code may also be made available under the following + Secondary Licenses when the conditions for such availability set forth + in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), + version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-grpc-java.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-grpc-java.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-grpc-java.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-gson.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-gson.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-gson.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-httpclient.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-httpclient.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-httpclient.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-httpcore.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-httpcore.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-httpcore.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-j2objc.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-j2objc.txt new file mode 100644 index 0000000000..2b004c3eee --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-j2objc.txt @@ -0,0 +1,232 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------------------------------------------------------------------- +The next section, BSD-3-Clause, applies to the files in: +jre_emul/android/platform/libcore/ojluni/src/main/java/java/time +-------------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of JSR-310 nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-annotations-2.14.0.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-annotations-2.14.0.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-annotations-2.14.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-annotations.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-annotations.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-annotations.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-core-2.14.0.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-core-2.14.0.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-core-2.14.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-core.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-core.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-core.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-databind-2.14.0.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-databind-2.14.0.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-databind-2.14.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-databind.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-databind.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-databind.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-dataformat-yaml.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-dataformat-yaml.txt new file mode 100644 index 0000000000..8d5775d40c --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-dataformat-yaml.txt @@ -0,0 +1,8 @@ +This copy of Jackson JSON processor YAML module is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-base-2.14.0.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-base-2.14.0.txt new file mode 100644 index 0000000000..6acf75483f --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-base-2.14.0.txt @@ -0,0 +1,8 @@ +This copy of Jackson JSON processor databind module is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-base.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-base.txt new file mode 100644 index 0000000000..6acf75483f --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-base.txt @@ -0,0 +1,8 @@ +This copy of Jackson JSON processor databind module is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-json-provider-2.14.0.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-json-provider-2.14.0.txt new file mode 100644 index 0000000000..6acf75483f --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-json-provider-2.14.0.txt @@ -0,0 +1,8 @@ +This copy of Jackson JSON processor databind module is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-json-provider.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-json-provider.txt new file mode 100644 index 0000000000..6acf75483f --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-jaxrs-json-provider.txt @@ -0,0 +1,8 @@ +This copy of Jackson JSON processor databind module is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-module-jaxb-annotations-2.14.0.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-module-jaxb-annotations-2.14.0.txt new file mode 100644 index 0000000000..283587f1b1 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-module-jaxb-annotations-2.14.0.txt @@ -0,0 +1,8 @@ +This copy of Jackson JSON processor `jackson-module-jaxb-annotations` module is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-module-jaxb-annotations.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-module-jaxb-annotations.txt new file mode 100644 index 0000000000..283587f1b1 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jackson-module-jaxb-annotations.txt @@ -0,0 +1,8 @@ +This copy of Jackson JSON processor `jackson-module-jaxb-annotations` module is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jaf-api.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jaf-api.txt new file mode 100644 index 0000000000..05220de312 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jaf-api.txt @@ -0,0 +1,29 @@ + + Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Eclipse Foundation, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jakarta.activation-api.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jakarta.activation-api.txt new file mode 100644 index 0000000000..e0358f9721 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jakarta.activation-api.txt @@ -0,0 +1,29 @@ + + Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Eclipse Foundation, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jakarta.activation.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jakarta.activation.txt new file mode 100644 index 0000000000..a8ba56ef14 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jakarta.activation.txt @@ -0,0 +1,277 @@ +# Eclipse Public License - v 2.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + + 1. DEFINITIONS + + "Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + + "Contributor" means any person or entity that Distributes the Program. + + "Licensed Patents" mean patent claims licensable by a Contributor which + are necessarily infringed by the use or sale of its Contribution alone + or when combined with the Program. + + "Program" means the Contributions Distributed in accordance with this + Agreement. + + "Recipient" means anyone who receives the Program under this Agreement + or any Secondary License (as applicable), including Contributors. + + "Derivative Works" shall mean any work, whether in Source Code or other + form, that is based on (or derived from) the Program and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. + + "Modified Works" shall mean any work in Source Code or other form that + results from an addition to, deletion from, or modification of the + contents of the Program, including, for purposes of clarity any new file + in Source Code form that contains any contents of the Program. Modified + Works shall not include works that contain only declarations, + interfaces, types, classes, structures, or files of the Program solely + in each case in order to link to, bind by name, or subclass the Program + or Modified Works thereof. + + "Distribute" means the acts of a) distributing or b) making available + in any manner that enables the transfer of a copy. + + "Source Code" means the form of a Program preferred for making + modifications, including but not limited to software source code, + documentation source, and configuration files. + + "Secondary License" means either the GNU General Public License, + Version 2.0, or any later versions of that license, including any + exceptions or additional permissions as identified by the initial + Contributor. + + 2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + + 3. REQUIREMENTS + + 3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + + 3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + + 3.3 Contributors may not remove or alter any copyright, patent, + trademark, attribution notices, disclaimers of warranty, or limitations + of liability ("notices") contained within the Program from any copy of + the Program which they Distribute, provided that Contributors may add + their own appropriate notices. + + 4. COMMERCIAL DISTRIBUTION + + Commercial distributors of software may accept certain responsibilities + with respect to end users, business partners and the like. While this + license is intended to facilitate the commercial use of the Program, + the Contributor who includes the Program in a commercial product + offering should do so in a manner which does not create potential + liability for other Contributors. Therefore, if a Contributor includes + the Program in a commercial product offering, such Contributor + ("Commercial Contributor") hereby agrees to defend and indemnify every + other Contributor ("Indemnified Contributor") against any losses, + damages and costs (collectively "Losses") arising from claims, lawsuits + and other legal actions brought by a third party against the Indemnified + Contributor to the extent caused by the acts or omissions of such + Commercial Contributor in connection with its distribution of the Program + in a commercial product offering. The obligations in this section do not + apply to any claims or Losses relating to any actual or alleged + intellectual property infringement. In order to qualify, an Indemnified + Contributor must: a) promptly notify the Commercial Contributor in + writing of such claim, and b) allow the Commercial Contributor to control, + and cooperate with the Commercial Contributor in, the defense and any + related settlement negotiations. The Indemnified Contributor may + participate in any such claim at its own expense. + + For example, a Contributor might include the Program in a commercial + product offering, Product X. That Contributor is then a Commercial + Contributor. If that Commercial Contributor then makes performance + claims, or offers warranties related to Product X, those performance + claims and warranties are such Commercial Contributor's responsibility + alone. Under this section, the Commercial Contributor would have to + defend claims against the other Contributors related to those performance + claims and warranties, and if a court requires any other Contributor to + pay any damages as a result, the Commercial Contributor must pay + those damages. + + 5. NO WARRANTY + + EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT + PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" + BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR + IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF + TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR + PURPOSE. Each Recipient is solely responsible for determining the + appropriateness of using and distributing the Program and assumes all + risks associated with its exercise of rights under this Agreement, + including but not limited to the risks and costs of program errors, + compliance with applicable laws, damage to or loss of data, programs + or equipment, and unavailability or interruption of operations. + + 6. DISCLAIMER OF LIABILITY + + EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT + PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS + SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST + PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE + EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + + 7. GENERAL + + If any provision of this Agreement is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of + the remainder of the terms of this Agreement, and without further + action by the parties hereto, such provision shall be reformed to the + minimum extent necessary to make such provision valid and enforceable. + + If Recipient institutes patent litigation against any entity + (including a cross-claim or counterclaim in a lawsuit) alleging that the + Program itself (excluding combinations of the Program with other software + or hardware) infringes such Recipient's patent(s), then such Recipient's + rights granted under Section 2(b) shall terminate as of the date such + litigation is filed. + + All Recipient's rights under this Agreement shall terminate if it + fails to comply with any of the material terms or conditions of this + Agreement and does not cure such failure in a reasonable period of + time after becoming aware of such noncompliance. If all Recipient's + rights under this Agreement terminate, Recipient agrees to cease use + and distribution of the Program as soon as reasonably practicable. + However, Recipient's obligations under this Agreement and any licenses + granted by Recipient relating to the Program shall continue and survive. + + Everyone is permitted to copy and distribute copies of this Agreement, + but in order to avoid inconsistency the Agreement is copyrighted and + may only be modified in the following manner. The Agreement Steward + reserves the right to publish new versions (including revisions) of + this Agreement from time to time. No one other than the Agreement + Steward has the right to modify this Agreement. The Eclipse Foundation + is the initial Agreement Steward. The Eclipse Foundation may assign the + responsibility to serve as the Agreement Steward to a suitable separate + entity. Each new version of the Agreement will be given a distinguishing + version number. The Program (including Contributions) may always be + Distributed subject to the version of the Agreement under which it was + received. In addition, after a new version of the Agreement is published, + Contributor may elect to Distribute the Program (including its + Contributions) under the new version. + + Except as expressly stated in Sections 2(a) and 2(b) above, Recipient + receives no rights or licenses to the intellectual property of any + Contributor under this Agreement, whether expressly, by implication, + estoppel or otherwise. All rights in the Program not expressly granted + under this Agreement are reserved. Nothing in this Agreement is intended + to be enforceable by any entity that is not a Contributor or Recipient. + No third-party beneficiary rights are created under this Agreement. + + Exhibit A - Form of Secondary Licenses Notice + + "This Source Code may also be made available under the following + Secondary Licenses when the conditions for such availability set forth + in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), + version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-javassist.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-javassist.txt new file mode 100644 index 0000000000..f45a423e3f --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-javassist.txt @@ -0,0 +1,357 @@ + + +Javassist License + + + + +
MOZILLA PUBLIC LICENSE
Version +1.1 +

+


+
+

1. Definitions. +

    1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. +

    1.1. ''Contributor'' means each entity that creates or contributes + to the creation of Modifications. +

    1.2. ''Contributor Version'' means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications made by + that particular Contributor. +

    1.3. ''Covered Code'' means the Original Code or Modifications or + the combination of the Original Code and Modifications, in each case including + portions thereof. +

    1.4. ''Electronic Distribution Mechanism'' means a mechanism + generally accepted in the software development community for the electronic + transfer of data. +

    1.5. ''Executable'' means Covered Code in any form other than Source + Code. +

    1.6. ''Initial Developer'' means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. +

    1.7. ''Larger Work'' means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. +

    1.8. ''License'' means this document. +

    1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or subsequently + acquired, any and all of the rights conveyed herein. +

    1.9. ''Modifications'' means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: +

      A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. +

      B. Any new file that contains any part of the Original Code or + previous Modifications.
       

    1.10. ''Original Code'' + means Source Code of computer software code which is described in the Source + Code notice required by Exhibit A as Original Code, and which, at the + time of its release under this License is not already Covered Code governed by + this License. +

    1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation,  method, process, and + apparatus claims, in any patent Licensable by grantor. +

    1.11. ''Source Code'' means the preferred form of the Covered Code + for making modifications to it, including all modules it contains, plus any + associated interface definition files, scripts used to control compilation and + installation of an Executable, or source code differential comparisons against + either the Original Code or another well known, available Covered Code of the + Contributor's choice. The Source Code can be in a compressed or archival form, + provided the appropriate decompression or de-archiving software is widely + available for no charge. +

    1.12. "You'' (or "Your")  means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this License + or a future version of this License issued under Section 6.1. For legal + entities, "You'' includes any entity which controls, is controlled by, or is + under common control with You. For purposes of this definition, "control'' + means (a) the power, direct or indirect, to cause the direction or management + of such entity, whether by contract or otherwise, or (b) ownership of more + than fifty percent (50%) of the outstanding shares or beneficial ownership of + such entity.

2. Source Code License. +
    2.1. The Initial Developer Grant.
    The Initial Developer hereby + grants You a world-wide, royalty-free, non-exclusive license, subject to third + party intellectual property claims: +
      (a)  under intellectual property rights (other than + patent or trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original Code (or + portions thereof) with or without Modifications, and/or as part of a Larger + Work; and +

      (b) under Patents Claims infringed by the making, using or selling + of Original Code, to make, have made, use, practice, sell, and offer for + sale, and/or otherwise dispose of the Original Code (or portions thereof). +

        +
        (c) the licenses granted in this Section 2.1(a) and (b) + are effective on the date Initial Developer first distributes Original Code + under the terms of this License. +

        (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) separate + from the Original Code;  or 3) for infringements caused by: i) the + modification of the Original Code or ii) the combination of the Original + Code with other software or devices.
         

      2.2. Contributor + Grant.
      Subject to third party intellectual property claims, each + Contributor hereby grants You a world-wide, royalty-free, non-exclusive + license +

        (a)  under intellectual property rights (other + than patent or trademark) Licensable by Contributor, to use, reproduce, + modify, display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an unmodified + basis, with other Modifications, as Covered Code and/or as part of a Larger + Work; and +

        (b) under Patent Claims infringed by the making, using, or selling + of  Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such + combination), to make, use, sell, offer for sale, have made, and/or + otherwise dispose of: 1) Modifications made by that Contributor (or portions + thereof); and 2) the combination of  Modifications made by that + Contributor with its Contributor Version (or portions of such + combination). +

        (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of the Covered + Code. +

        (d)    Notwithstanding Section 2.2(b) above, no + patent license is granted: 1) for any code that Contributor has deleted from + the Contributor Version; 2)  separate from the Contributor + Version;  3)  for infringements caused by: i) third party + modifications of Contributor Version or ii)  the combination of + Modifications made by that Contributor with other software  (except as + part of the Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by that + Contributor.

    +


    3. Distribution Obligations. +

      3.1. Application of License.
      The Modifications which You create + or to which You contribute are governed by the terms of this License, + including without limitation Section 2.2. The Source Code version of + Covered Code may be distributed only under the terms of this License or a + future version of this License released under Section 6.1, and You must + include a copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code version + that alters or restricts the applicable version of this License or the + recipients' rights hereunder. However, You may include an additional document + offering the additional rights described in Section 3.5. +

      3.2. Availability of Source Code.
      Any Modification which You + create or to which You contribute must be made available in Source Code form + under the terms of this License either on the same media as an Executable + version or via an accepted Electronic Distribution Mechanism to anyone to whom + you made an Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) months + after the date it initially became available, or at least six (6) months after + a subsequent version of that particular Modification has been made available + to such recipients. You are responsible for ensuring that the Source Code + version remains available even if the Electronic Distribution Mechanism is + maintained by a third party. +

      3.3. Description of Modifications.
      You must cause all Covered + Code to which You contribute to contain a file documenting the changes You + made to create that Covered Code and the date of any change. You must include + a prominent statement that the Modification is derived, directly or + indirectly, from Original Code provided by the Initial Developer and including + the name of the Initial Developer in (a) the Source Code, and (b) in any + notice in an Executable version or related documentation in which You describe + the origin or ownership of the Covered Code. +

      3.4. Intellectual Property Matters +

        (a) Third Party Claims.
        If Contributor has knowledge that a + license under a third party's intellectual property rights is required to + exercise the rights granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code distribution + titled "LEGAL'' which describes the claim and the party making the claim in + sufficient detail that a recipient will know whom to contact. If Contributor + obtains such knowledge after the Modification is made available as described + in Section 3.2, Contributor shall promptly modify the LEGAL file in all + copies Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) reasonably + calculated to inform those who received the Covered Code that new knowledge + has been obtained. +

        (b) Contributor APIs.
        If Contributor's Modifications include + an application programming interface and Contributor has knowledge of patent + licenses which are reasonably necessary to implement that API, Contributor + must also include this information in the LEGAL file. +
         

                + (c)    Representations. +
        Contributor represents that, except as disclosed pursuant to Section + 3.4(a) above, Contributor believes that Contributor's Modifications are + Contributor's original creation(s) and/or Contributor has sufficient rights + to grant the rights conveyed by this License.
      +


      3.5. Required Notices.
      You must duplicate the notice in + Exhibit A in each file of the Source Code.  If it is not possible + to put such notice in a particular Source Code file due to its structure, then + You must include such notice in a location (such as a relevant directory) + where a user would be likely to look for such a notice.  If You created + one or more Modification(s) You may add your name as a Contributor to the + notice described in Exhibit A.  You must also duplicate this + License in any documentation for the Source Code where You describe + recipients' rights or ownership rights relating to Covered Code.  You may + choose to offer, and to charge a fee for, warranty, support, indemnity or + liability obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial Developer + or any Contributor. You must make it absolutely clear than any such warranty, + support, indemnity or liability obligation is offered by You alone, and You + hereby agree to indemnify the Initial Developer and every Contributor for any + liability incurred by the Initial Developer or such Contributor as a result of + warranty, support, indemnity or liability terms You offer. +

      3.6. Distribution of Executable Versions.
      You may distribute + Covered Code in Executable form only if the requirements of Section + 3.1-3.5 have been met for that Covered Code, and if You include a + notice stating that the Source Code version of the Covered Code is available + under the terms of this License, including a description of how and where You + have fulfilled the obligations of Section 3.2. The notice must be + conspicuously included in any notice in an Executable version, related + documentation or collateral in which You describe recipients' rights relating + to the Covered Code. You may distribute the Executable version of Covered Code + or ownership rights under a license of Your choice, which may contain terms + different from this License, provided that You are in compliance with the + terms of this License and that the license for the Executable version does not + attempt to limit or alter the recipient's rights in the Source Code version + from the rights set forth in this License. If You distribute the Executable + version under a different license You must make it absolutely clear that any + terms which differ from this License are offered by You alone, not by the + Initial Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of any such terms You offer. + +

      3.7. Larger Works.
      You may create a Larger Work by combining + Covered Code with other code not governed by the terms of this License and + distribute the Larger Work as a single product. In such a case, You must make + sure the requirements of this License are fulfilled for the Covered +Code.

    4. Inability to Comply Due to Statute or Regulation. +
      If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to statute, + judicial order, or regulation then You must: (a) comply with the terms of this + License to the maximum extent possible; and (b) describe the limitations and + the code they affect. Such description must be included in the LEGAL file + described in Section 3.4 and must be included with all distributions of + the Source Code. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it.
    5. Application of this License. +
      This License applies to code to which the Initial Developer has attached + the notice in Exhibit A and to related Covered Code.
    6. Versions +of the License. +
      6.1. New Versions.
      Netscape Communications Corporation + (''Netscape'') may publish revised and/or new versions of the License from + time to time. Each version will be given a distinguishing version number. +

      6.2. Effect of New Versions.
      Once Covered Code has been + published under a particular version of the License, You may always continue + to use it under the terms of that version. You may also choose to use such + Covered Code under the terms of any subsequent version of the License + published by Netscape. No one other than Netscape has the right to modify the + terms applicable to Covered Code created under this License. +

      6.3. Derivative Works.
      If You create or use a modified version + of this License (which you may only do in order to apply it to code which is + not already Covered Code governed by this License), You must (a) rename Your + license so that the phrases ''Mozilla'', ''MOZILLAPL'', ''MOZPL'', + ''Netscape'', "MPL", ''NPL'' or any confusingly similar phrase do not appear + in your license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license contains + terms which differ from the Mozilla Public License and Netscape Public + License. (Filling in the name of the Initial Developer, Original Code or + Contributor in the notice described in Exhibit A shall not of + themselves be deemed to be modifications of this License.)

    7. +DISCLAIMER OF WARRANTY. +
      COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS'' BASIS, WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT + LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, + FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE + QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED + CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY + OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR + CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS + DISCLAIMER.
    8. TERMINATION. +
      8.1.  This License and the rights granted hereunder will + terminate automatically if You fail to comply with terms herein and fail to + cure such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall survive any + termination of this License. Provisions which, by their nature, must remain in + effect beyond the termination of this License shall survive. +

      8.2.  If You initiate litigation by asserting a patent + infringement claim (excluding declatory judgment actions) against Initial + Developer or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant")  alleging that: +

      (a)  such Participant's Contributor Version directly or + indirectly infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon + 60 days notice from Participant terminate prospectively, unless if within 60 + days after receipt of notice You either: (i)  agree in writing to pay + Participant a mutually agreeable reasonable royalty for Your past and future + use of Modifications made by such Participant, or (ii) withdraw Your + litigation claim with respect to the Contributor Version against such + Participant.  If within 60 days of notice, a reasonable royalty and + payment arrangement are not mutually agreed upon in writing by the parties or + the litigation claim is not withdrawn, the rights granted by Participant to + You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. +

      (b)  any software, hardware, or device, other than such + Participant's Contributor Version, directly or indirectly infringes any + patent, then any rights granted to You by such Participant under Sections + 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that Participant. +

      8.3.  If You assert a patent infringement claim against + Participant alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as by + license or settlement) prior to the initiation of patent infringement + litigation, then the reasonable value of the licenses granted by such + Participant under Sections 2.1 or 2.2 shall be taken into account in + determining the amount or value of any payment or license. +

      8.4.  In the event of termination under Sections 8.1 or 8.2 + above,  all end user license agreements (excluding distributors and + resellers) which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination.

    9. LIMITATION OF +LIABILITY. +
      UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING + NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY + OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY + OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, + INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR + MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH + PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS + LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL + INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR + LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND + LIMITATION MAY NOT APPLY TO YOU.
    10. U.S. GOVERNMENT END USERS. +
      The Covered Code is a ''commercial item,'' as that term is defined in 48 + C.F.R. 2.101 (Oct. 1995), consisting of ''commercial computer software'' and + ''commercial computer software documentation,'' as such terms are used in 48 + C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. + 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users + acquire Covered Code with only those rights set forth herein.
    11. +MISCELLANEOUS. +
      This License represents the complete agreement concerning subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. This License shall be governed by California law provisions + (except to the extent applicable law, if any, provides otherwise), excluding + its conflict-of-law provisions. With respect to disputes in which at least one + party is a citizen of, or an entity chartered or registered to do business in + the United States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern District of + California, with venue lying in Santa Clara County, California, with the + losing party responsible for costs, including without limitation, court costs + and reasonable attorneys' fees and expenses. The application of the United + Nations Convention on Contracts for the International Sale of Goods is + expressly excluded. Any law or regulation which provides that the language of + a contract shall be construed against the drafter shall not apply to this + License.
    12. RESPONSIBILITY FOR CLAIMS. +
      As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, out of its + utilization of rights under this License and You agree to work with Initial + Developer and Contributors to distribute such responsibility on an equitable + basis. Nothing herein is intended or shall be deemed to constitute any + admission of liability.
    13. MULTIPLE-LICENSED CODE. +
      Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed".  "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under Your + choice of the MPL or the alternative licenses, if any, specified by the + Initial Developer in the file described in Exhibit A.
    +


    EXHIBIT A -Mozilla Public License. +

      The contents of this file are subject to the Mozilla Public License + Version 1.1 (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.mozilla.org/MPL/ +

      Software distributed under the License is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + for the specific language governing rights and limitations under the + License. +

      The Original Code is Javassist. +

      The Initial Developer of the Original Code is Shigeru Chiba. + Portions created by the Initial Developer are
        + Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. +

      Contributor(s): __Bill Burke, Jason T. Greene______________. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-javax.activation-api-1.2.0-sources.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-javax.activation-api-1.2.0-sources.txt new file mode 100644 index 0000000000..596a510633 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-javax.activation-api-1.2.0-sources.txt @@ -0,0 +1,362 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1 + +1. Definitions. + + 1.1. "Contributor" means each individual or entity that creates or + contributes to the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Software, prior Modifications used by a Contributor (if any), and + the Modifications made by that particular Contributor. + + 1.3. "Covered Software" means (a) the Original Software, or (b) + Modifications, or (c) the combination of files containing Original + Software with files containing Modifications, in each case including + portions thereof. + + 1.4. "Executable" means the Covered Software in any form other than + Source Code. + + 1.5. "Initial Developer" means the individual or entity that first + makes Original Software available under this License. + + 1.6. "Larger Work" means a work which combines Covered Software or + portions thereof with code not governed by the terms of this License. + + 1.7. "License" means this document. + + 1.8. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means the Source Code and Executable form of + any of the following: + + A. Any file that results from an addition to, deletion from or + modification of the contents of a file containing Original Software + or previous Modifications; + + B. Any new file that contains any part of the Original Software or + previous Modification; or + + C. Any new file that is contributed or otherwise made available + under the terms of this License. + + 1.10. "Original Software" means the Source Code and Executable form + of computer software code that is originally released under this + License. + + 1.11. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.12. "Source Code" means (a) the common form of computer software + code in which modifications are made and (b) associated + documentation included in or with such code. + + 1.13. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, + this License. For legal entities, "You" includes any entity which + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject + to third party intellectual property claims, the Initial Developer + hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer, to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Software (or portions thereof), with or without Modifications, + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of + Original Software, to make, have made, use, practice, sell, and + offer for sale, and/or otherwise dispose of the Original Software + (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on + the date Initial Developer first distributes or otherwise makes the + Original Software available to a third party under the terms of this + License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: (1) for code that You delete from the Original Software, or + (2) for infringements caused by: (i) the modification of the + Original Software, or (ii) the combination of the Original Software + with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject + to third party intellectual property claims, each Contributor hereby + grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof), either on an + unmodified basis, with other Modifications, as Covered Software + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling + of Modifications made by that Contributor either alone and/or in + combination with its Contributor Version (or portions of such + combination), to make, use, sell, offer for sale, have made, and/or + otherwise dispose of: (1) Modifications made by that Contributor (or + portions thereof); and (2) the combination of Modifications made by + that Contributor with its Contributor Version (or portions of such + combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective + on the date Contributor first distributes or otherwise makes the + Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: (1) for any code that Contributor has deleted from the + Contributor Version; (2) for infringements caused by: (i) third + party modifications of Contributor Version, or (ii) the combination + of Modifications made by that Contributor with other software + (except as part of the Contributor Version) or other devices; or (3) + under Patent Claims infringed by Covered Software in the absence of + Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make available + in Executable form must also be made available in Source Code form + and that Source Code form must be distributed only under the terms + of this License. You must include a copy of this License with every + copy of the Source Code form of the Covered Software You distribute + or otherwise make available. You must inform recipients of any such + Covered Software in Executable form as to how they can obtain such + Covered Software in Source Code form in a reasonable manner on or + through a medium customarily used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are + governed by the terms of this License. You represent that You + believe Your Modifications are Your original creation(s) and/or You + have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that + identifies You as the Contributor of the Modification. You may not + remove or alter any copyright, patent or trademark notices contained + within the Covered Software, or any notices of licensing or any + descriptive text giving attribution to any Contributor or the + Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in + Source Code form that alters or restricts the applicable version of + this License or the recipients' rights hereunder. You may choose to + offer, and to charge a fee for, warranty, support, indemnity or + liability obligations to one or more recipients of Covered Software. + However, you may do so only on Your own behalf, and not on behalf of + the Initial Developer or any Contributor. You must make it + absolutely clear that any such warranty, support, indemnity or + liability obligation is offered by You alone, and You hereby agree + to indemnify the Initial Developer and every Contributor for any + liability incurred by the Initial Developer or such Contributor as a + result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software under + the terms of this License or under the terms of a license of Your + choice, which may contain terms different from this License, + provided that You are in compliance with the terms of this License + and that the license for the Executable form does not attempt to + limit or alter the recipient's rights in the Source Code form from + the rights set forth in this License. If You distribute the Covered + Software in Executable form under a different license, You must make + it absolutely clear that any terms which differ from this License + are offered by You alone, not by the Initial Developer or + Contributor. You hereby agree to indemnify the Initial Developer and + every Contributor for any liability incurred by the Initial + Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with + other code not governed by the terms of this License and distribute + the Larger Work as a single product. In such a case, You must make + sure the requirements of this License are fulfilled for the Covered + Software. + +4. Versions of the License. + + 4.1. New Versions. + + Oracle is the initial license steward and may publish revised and/or + new versions of this License from time to time. Each version will be + given a distinguishing version number. Except as provided in Section + 4.3, no one other than the license steward has the right to modify + this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the + Covered Software available under the terms of the version of the + License under which You originally received the Covered Software. If + the Initial Developer includes a notice in the Original Software + prohibiting it from being distributed or otherwise made available + under any subsequent version of the License, You must distribute and + make the Covered Software available under the terms of the version + of the License under which You originally received the Covered + Software. Otherwise, You may also choose to use, distribute or + otherwise make the Covered Software available under the terms of any + subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new + license for Your Original Software, You may create and use a + modified version of this License if You: (a) rename the license and + remove any references to the name of the license steward (except to + note that the license differs from this License); and (b) otherwise + make it clear that the license contains terms which differ from this + License. + +5. DISCLAIMER OF WARRANTY. + + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE + IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR + NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF + THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE + DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY + OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, + REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS + AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to + cure such breach within 30 days of becoming aware of the breach. + Provisions which, by their nature, must remain in effect beyond the + termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding + declaratory judgment actions) against Initial Developer or a + Contributor (the Initial Developer or Contributor against whom You + assert such claim is referred to as "Participant") alleging that the + Participant Software (meaning the Contributor Version where the + Participant is a Contributor or the Original Software where the + Participant is the Initial Developer) directly or indirectly + infringes any patent, then any and all rights granted directly or + indirectly to You by such Participant, the Initial Developer (if the + Initial Developer is not the Participant) and all Contributors under + Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice + from Participant terminate prospectively and automatically at the + expiration of such 60 day notice period, unless if within such 60 + day period You withdraw Your claim with respect to the Participant + Software against such Participant either unilaterally or pursuant to + a written agreement with Participant. + + 6.3. If You assert a patent infringement claim against Participant + alleging that the Participant Software directly or indirectly + infringes any patent where such claim is resolved (such as by + license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 6.4. In the event of termination under Sections 6.1 or 6.2 above, + all end user licenses that have been validly granted by You or any + distributor hereunder prior to termination (excluding licenses + granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF + COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE + TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER + FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR + LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE + POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT + APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH + PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH + LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR + LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION + AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + + The Covered Software is a "commercial item," as that term is defined + in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" (as that term is defined at 48 C.F.R. � + 252.227-7014(a)(1)) and "commercial computer software documentation" + as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent + with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 + (June 1995), all U.S. Government End Users acquire Covered Software + with only those rights set forth herein. This U.S. Government Rights + clause is in lieu of, and supersedes, any other FAR, DFAR, or other + clause or provision that addresses Government rights in computer + software under this License. + +9. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + the law of the jurisdiction specified in a notice contained within + the Original Software (except to the extent applicable law, if any, + provides otherwise), excluding such jurisdiction's conflict-of-law + provisions. Any litigation relating to this License shall be subject + to the jurisdiction of the courts located in the jurisdiction and + venue specified in a notice contained within the Original Software, + with the losing party responsible for costs, including, without + limitation, court costs and reasonable attorneys' fees and expenses. + The application of the United Nations Convention on Contracts for + the International Sale of Goods is expressly excluded. Any law or + regulation which provides that the language of a contract shall be + construed against the drafter shall not apply to this License. You + agree that You alone are responsible for compliance with the United + States export administration regulations (and the export control + laws and regulation of any other countries) when You use, distribute + or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +------------------------------------------------------------------------ + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION +LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the +State of California (excluding conflict-of-law provisions). Any +litigation relating to this License shall be subject to the jurisdiction +of the Federal Courts of the Northern District of California and the +state courts of the State of California, with venue lying in Santa Clara +County, California. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jaxb-ri.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jaxb-ri.txt new file mode 100644 index 0000000000..74b62b6219 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jaxb-ri.txt @@ -0,0 +1,11 @@ +Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +Neither the name of the Eclipse Foundation, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-joda-time.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-joda-time.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-joda-time.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jsonp.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jsonp.txt new file mode 100644 index 0000000000..4a00ba9482 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-jsonp.txt @@ -0,0 +1,362 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1 + +1. Definitions. + + 1.1. "Contributor" means each individual or entity that creates or + contributes to the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Software, prior Modifications used by a Contributor (if any), and + the Modifications made by that particular Contributor. + + 1.3. "Covered Software" means (a) the Original Software, or (b) + Modifications, or (c) the combination of files containing Original + Software with files containing Modifications, in each case including + portions thereof. + + 1.4. "Executable" means the Covered Software in any form other than + Source Code. + + 1.5. "Initial Developer" means the individual or entity that first + makes Original Software available under this License. + + 1.6. "Larger Work" means a work which combines Covered Software or + portions thereof with code not governed by the terms of this License. + + 1.7. "License" means this document. + + 1.8. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means the Source Code and Executable form of + any of the following: + + A. Any file that results from an addition to, deletion from or + modification of the contents of a file containing Original Software + or previous Modifications; + + B. Any new file that contains any part of the Original Software or + previous Modification; or + + C. Any new file that is contributed or otherwise made available + under the terms of this License. + + 1.10. "Original Software" means the Source Code and Executable form + of computer software code that is originally released under this + License. + + 1.11. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.12. "Source Code" means (a) the common form of computer software + code in which modifications are made and (b) associated + documentation included in or with such code. + + 1.13. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, + this License. For legal entities, "You" includes any entity which + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject + to third party intellectual property claims, the Initial Developer + hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer, to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Software (or portions thereof), with or without Modifications, + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of + Original Software, to make, have made, use, practice, sell, and + offer for sale, and/or otherwise dispose of the Original Software + (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on + the date Initial Developer first distributes or otherwise makes the + Original Software available to a third party under the terms of this + License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: (1) for code that You delete from the Original Software, or + (2) for infringements caused by: (i) the modification of the + Original Software, or (ii) the combination of the Original Software + with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject + to third party intellectual property claims, each Contributor hereby + grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof), either on an + unmodified basis, with other Modifications, as Covered Software + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling + of Modifications made by that Contributor either alone and/or in + combination with its Contributor Version (or portions of such + combination), to make, use, sell, offer for sale, have made, and/or + otherwise dispose of: (1) Modifications made by that Contributor (or + portions thereof); and (2) the combination of Modifications made by + that Contributor with its Contributor Version (or portions of such + combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective + on the date Contributor first distributes or otherwise makes the + Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: (1) for any code that Contributor has deleted from the + Contributor Version; (2) for infringements caused by: (i) third + party modifications of Contributor Version, or (ii) the combination + of Modifications made by that Contributor with other software + (except as part of the Contributor Version) or other devices; or (3) + under Patent Claims infringed by Covered Software in the absence of + Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make available + in Executable form must also be made available in Source Code form + and that Source Code form must be distributed only under the terms + of this License. You must include a copy of this License with every + copy of the Source Code form of the Covered Software You distribute + or otherwise make available. You must inform recipients of any such + Covered Software in Executable form as to how they can obtain such + Covered Software in Source Code form in a reasonable manner on or + through a medium customarily used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are + governed by the terms of this License. You represent that You + believe Your Modifications are Your original creation(s) and/or You + have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that + identifies You as the Contributor of the Modification. You may not + remove or alter any copyright, patent or trademark notices contained + within the Covered Software, or any notices of licensing or any + descriptive text giving attribution to any Contributor or the + Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in + Source Code form that alters or restricts the applicable version of + this License or the recipients' rights hereunder. You may choose to + offer, and to charge a fee for, warranty, support, indemnity or + liability obligations to one or more recipients of Covered Software. + However, you may do so only on Your own behalf, and not on behalf of + the Initial Developer or any Contributor. You must make it + absolutely clear that any such warranty, support, indemnity or + liability obligation is offered by You alone, and You hereby agree + to indemnify the Initial Developer and every Contributor for any + liability incurred by the Initial Developer or such Contributor as a + result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software under + the terms of this License or under the terms of a license of Your + choice, which may contain terms different from this License, + provided that You are in compliance with the terms of this License + and that the license for the Executable form does not attempt to + limit or alter the recipient's rights in the Source Code form from + the rights set forth in this License. If You distribute the Covered + Software in Executable form under a different license, You must make + it absolutely clear that any terms which differ from this License + are offered by You alone, not by the Initial Developer or + Contributor. You hereby agree to indemnify the Initial Developer and + every Contributor for any liability incurred by the Initial + Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with + other code not governed by the terms of this License and distribute + the Larger Work as a single product. In such a case, You must make + sure the requirements of this License are fulfilled for the Covered + Software. + +4. Versions of the License. + + 4.1. New Versions. + + Oracle is the initial license steward and may publish revised and/or + new versions of this License from time to time. Each version will be + given a distinguishing version number. Except as provided in Section + 4.3, no one other than the license steward has the right to modify + this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the + Covered Software available under the terms of the version of the + License under which You originally received the Covered Software. If + the Initial Developer includes a notice in the Original Software + prohibiting it from being distributed or otherwise made available + under any subsequent version of the License, You must distribute and + make the Covered Software available under the terms of the version + of the License under which You originally received the Covered + Software. Otherwise, You may also choose to use, distribute or + otherwise make the Covered Software available under the terms of any + subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new + license for Your Original Software, You may create and use a + modified version of this License if You: (a) rename the license and + remove any references to the name of the license steward (except to + note that the license differs from this License); and (b) otherwise + make it clear that the license contains terms which differ from this + License. + +5. DISCLAIMER OF WARRANTY. + + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE + IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR + NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF + THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE + DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY + OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, + REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS + AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to + cure such breach within 30 days of becoming aware of the breach. + Provisions which, by their nature, must remain in effect beyond the + termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding + declaratory judgment actions) against Initial Developer or a + Contributor (the Initial Developer or Contributor against whom You + assert such claim is referred to as "Participant") alleging that the + Participant Software (meaning the Contributor Version where the + Participant is a Contributor or the Original Software where the + Participant is the Initial Developer) directly or indirectly + infringes any patent, then any and all rights granted directly or + indirectly to You by such Participant, the Initial Developer (if the + Initial Developer is not the Participant) and all Contributors under + Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice + from Participant terminate prospectively and automatically at the + expiration of such 60 day notice period, unless if within such 60 + day period You withdraw Your claim with respect to the Participant + Software against such Participant either unilaterally or pursuant to + a written agreement with Participant. + + 6.3. If You assert a patent infringement claim against Participant + alleging that the Participant Software directly or indirectly + infringes any patent where such claim is resolved (such as by + license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 6.4. In the event of termination under Sections 6.1 or 6.2 above, + all end user licenses that have been validly granted by You or any + distributor hereunder prior to termination (excluding licenses + granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF + COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE + TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER + FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR + LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE + POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT + APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH + PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH + LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR + LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION + AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + + The Covered Software is a "commercial item," as that term is defined + in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" (as that term is defined at 48 C.F.R. § + 252.227-7014(a)(1)) and "commercial computer software documentation" + as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent + with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 + (June 1995), all U.S. Government End Users acquire Covered Software + with only those rights set forth herein. This U.S. Government Rights + clause is in lieu of, and supersedes, any other FAR, DFAR, or other + clause or provision that addresses Government rights in computer + software under this License. + +9. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + the law of the jurisdiction specified in a notice contained within + the Original Software (except to the extent applicable law, if any, + provides otherwise), excluding such jurisdiction's conflict-of-law + provisions. Any litigation relating to this License shall be subject + to the jurisdiction of the courts located in the jurisdiction and + venue specified in a notice contained within the Original Software, + with the losing party responsible for costs, including, without + limitation, court costs and reasonable attorneys' fees and expenses. + The application of the United Nations Convention on Contracts for + the International Sale of Goods is expressly excluded. Any law or + regulation which provides that the language of a contract shall be + construed against the drafter shall not apply to this License. You + agree that You alone are responsible for compliance with the United + States export administration regulations (and the export control + laws and regulation of any other countries) when You use, distribute + or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +------------------------------------------------------------------------ + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION +LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the +State of California (excluding conflict-of-law provisions). Any +litigation relating to this License shall be subject to the jurisdiction +of the Federal Courts of the Northern District of California and the +state courts of the State of California, with venue lying in Santa Clara +County, California. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-junit5.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-junit5.txt new file mode 100644 index 0000000000..8ebced110a --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-junit5.txt @@ -0,0 +1,98 @@ +Eclipse Public License - v 2.0 +============================== + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (“AGREEMENT”). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +### 1. Definitions + +“Contribution” means: +* **a)** in the case of the initial Contributor, the initial content Distributed under this Agreement, and +* **b)** in the case of each subsequent Contributor: + * **i)** changes to the Program, and + * **ii)** additions to the Program; +where such changes and/or additions to the Program originate from and are Distributed by that particular Contributor. A Contribution “originates” from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include changes or additions to the Program that are not Modified Works. + +“Contributor” means any person or entity that Distributes the Program. + +“Licensed Patents” mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +“Program” means the Contributions Distributed in accordance with this Agreement. + +“Recipient” means anyone who receives the Program under this Agreement or any Secondary License (as applicable), including Contributors. + +“Derivative Works” shall mean any work, whether in Source Code or other form, that is based on (or derived from) the Program and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. + +“Modified Works” shall mean any work in Source Code or other form that results from an addition to, deletion from, or modification of the contents of the Program, including, for purposes of clarity any new file in Source Code form that contains any contents of the Program. Modified Works shall not include works that contain only declarations, interfaces, types, classes, structures, or files of the Program solely in each case in order to link to, bind by name, or subclass the Program or Modified Works thereof. + +“Distribute” means the acts of **a)** distributing or **b)** making available in any manner that enables the transfer of a copy. + +“Source Code” means the form of a Program preferred for making modifications, including but not limited to software source code, documentation source, and configuration files. + +“Secondary License” means either the GNU General Public License, Version 2.0, or any later versions of that license, including any exceptions or additional permissions as identified by the initial Contributor. + +### 2. Grant of Rights + +**a)** Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, Distribute and sublicense the Contribution of such Contributor, if any, and such Derivative Works. + +**b)** Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in Source Code or other form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. + +**c)** Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to Distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. + +**d)** Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. + +**e)** Notwithstanding the terms of any Secondary License, no Contributor makes additional grants to any Recipient (other than those set forth in this Agreement) as a result of such Recipient's receipt of the Program under the terms of a Secondary License (if permitted under the terms of Section 3). + +### 3. Requirements + +**3.1** If a Contributor Distributes the Program in any form, then: + +* **a)** the Program must also be made available as Source Code, in accordance with section 3.2, and the Contributor must accompany the Program with a statement that the Source Code for the Program is available under this Agreement, and informs Recipients how to obtain it in a reasonable manner on or through a medium customarily used for software exchange; and + +* **b)** the Contributor may Distribute the Program under a license different than this Agreement, provided that such license: + * **i)** effectively disclaims on behalf of all other Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; + * **ii)** effectively excludes on behalf of all other Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; + * **iii)** does not attempt to limit or alter the recipients' rights in the Source Code under section 3.2; and + * **iv)** requires any subsequent distribution of the Program by any party to be under a license that satisfies the requirements of this section 3. + +**3.2** When the Program is Distributed as Source Code: + +* **a)** it must be made available under this Agreement, or if the Program **(i)** is combined with other material in a separate file or files made available under a Secondary License, and **(ii)** the initial Contributor attached to the Source Code the notice described in Exhibit A of this Agreement, then the Program may be made available under the terms of such Secondary Licenses, and +* **b)** a copy of this Agreement must be included with each copy of the Program. + +**3.3** Contributors may not remove or alter any copyright, patent, trademark, attribution notices, disclaimers of warranty, or limitations of liability (“notices”) contained within the Program from any copy of the Program which they Distribute, provided that Contributors may add their own appropriate notices. + +### 4. Commercial Distribution + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor (“Commercial Contributor”) hereby agrees to defend and indemnify every other Contributor (“Indemnified Contributor”) against any losses, damages and costs (collectively “Losses”) arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: **a)** promptly notify the Commercial Contributor in writing of such claim, and **b)** allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +### 5. No Warranty + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +### 6. Disclaimer of Liability + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +### 7. General + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be Distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to Distribute the Program (including its Contributions) under the new version. + +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. Nothing in this Agreement is intended to be enforceable by any entity that is not a Contributor or Recipient. No third-party beneficiary rights are created under this Agreement. + +#### Exhibit A - Form of Secondary Licenses Notice + +> “This Source Code may also be made available under the following Secondary Licenses when the conditions for such availability set forth in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), version(s), and exceptions or additional permissions here}.” + +Simply including a copy of this Agreement, including this Exhibit A is not sufficient to license the Source Code under Secondary Licenses. + +If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-log4j-api.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-log4j-api.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-log4j-api.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-log4j-core.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-log4j-core.txt new file mode 100644 index 0000000000..6279e5206d --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-log4j-core.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 1999-2005 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-log4j-slf4j-impl.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-log4j-slf4j-impl.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-log4j-slf4j-impl.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-netty.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-netty.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-netty.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://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. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-okhttp.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-okhttp.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-okhttp.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-opentracing-java.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-opentracing-java.txt new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-opentracing-java.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-perfmark.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-perfmark.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-perfmark.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-protobuf.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-protobuf.txt new file mode 100644 index 0000000000..97a6e3d199 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-protobuf.txt @@ -0,0 +1,32 @@ +Copyright 2008 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-slf4j.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-slf4j.txt new file mode 100644 index 0000000000..a51675a21c --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-slf4j.txt @@ -0,0 +1,23 @@ +Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland) +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-bolt.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-bolt.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-bolt.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-boot.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-boot.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-boot.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-common-tools.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-common-tools.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-common-tools.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-hessian.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-hessian.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-hessian.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-lookout.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-lookout.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-lookout.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-rpc.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-rpc.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-sofa-rpc.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-swagger-annotations.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-swagger-annotations.txt new file mode 100644 index 0000000000..e280013182 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-swagger-annotations.txt @@ -0,0 +1,11 @@ +Copyright 2016 SmartBear Software + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at [apache.org/licenses/LICENSE-2.0](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. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-swagger-core.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-swagger-core.txt new file mode 100644 index 0000000000..3e5194180d --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-swagger-core.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2015. SmartBear Software Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-swagger-models.txt b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-swagger-models.txt new file mode 100644 index 0000000000..e280013182 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/release-docs/licenses/LICENSE-swagger-models.txt @@ -0,0 +1,11 @@ +Copyright 2016 SmartBear Software + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at [apache.org/licenses/LICENSE-2.0](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. \ No newline at end of file diff --git a/hugegraph-commons/hugegraph-dist/scripts/apache-release.sh b/hugegraph-commons/hugegraph-dist/scripts/apache-release.sh new file mode 100755 index 0000000000..66faae9ce9 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/scripts/apache-release.sh @@ -0,0 +1,105 @@ +#!/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. +# + +GROUP="hugegraph" +# current repository name +REPO="${GROUP}-commons" +# release version (input by committer) +RELEASE_VERSION=$1 +USERNAME=$2 +PASSWORD=$3 +# git release branch (check it carefully) +GIT_BRANCH="release-${RELEASE_VERSION}" + +RELEASE_VERSION=${RELEASE_VERSION:?"Please input the release version behind script"} + +WORK_DIR=$( + cd "$(dirname "$0")" || exit + pwd +) +cd "${WORK_DIR}" || exit +echo "In the work dir: $(pwd)" + +# clean old dir then build a new one +rm -rf dist && mkdir -p dist/apache-${REPO} + +# step1: package the source code +cd ../../ || exit +git archive --format=tar.gz \ + --output="${GROUP}-dist/scripts/dist/apache-${REPO}/apache-${REPO}-incubating-${RELEASE_VERSION}-src.tar.gz" \ + --prefix="apache-${REPO}-incubating-${RELEASE_VERSION}-src/" "${GIT_BRANCH}" || exit + +cd - || exit + +# step2: copy the binary file (Optional) +# Note: it's optional for project to generate binary package (skip this step if not need) +#cp -v ../../target/apache-${REPO}-incubating-"${RELEASE_VERSION}".tar.gz \ +# dist/apache-${REPO} || exit + +# step3: sign + hash +##### 3.1 sign in source & binary package +gpg --version 1>/dev/null || exit +cd ./dist/apache-${REPO} || exit +for i in *.tar.gz; do + echo "$i" && gpg --armor --output "$i".asc --detach-sig "$i" +done + +##### 3.2 Generate SHA512 file +shasum --version 1>/dev/null || exit +for i in *.tar.gz; do + shasum -a 512 "$i" | tee "$i".sha512 +done + +#### 3.3 check signature & sha512 +echo "#### start to check signature & hashcode ####" +for i in *.tar.gz; do + echo "$i" + gpg --verify "$i".asc "$i" || exit +done + +for i in *.tar.gz; do + echo "$i" + shasum -a 512 --check "$i".sha512 || exit +done + +# step4: upload to Apache-SVN +SVN_DIR="${GROUP}-svn-dev" +cd ../ +rm -rfv ${SVN_DIR} + +##### 4.1 pull from remote & copy files +svn co "https://dist.apache.org/repos/dist/dev/incubator/${GROUP}" ${SVN_DIR} +mkdir -p ${SVN_DIR}/"${RELEASE_VERSION}" +cp -v apache-${REPO}/*tar.gz* "${SVN_DIR}/${RELEASE_VERSION}" +cd ${SVN_DIR} || exit + +##### 4.2 check status first +svn status +svn add --parents "${RELEASE_VERSION}"/apache-${REPO}-* +# check status again +svn status + +##### 4.3 commit & push files +if [ "$USERNAME" = "" ]; then + svn commit -m "submit files for ${REPO} ${RELEASE_VERSION}" || exit +else + svn commit -m "submit files for ${REPO} ${RELEASE_VERSION}" \ + --username "${USERNAME}" --password "${PASSWORD}" || exit +fi + +echo "Finished all, please check all steps in script manually again!" diff --git a/hugegraph-commons/hugegraph-dist/scripts/dependency/check_dependencies.sh b/hugegraph-commons/hugegraph-dist/scripts/dependency/check_dependencies.sh new file mode 100644 index 0000000000..642c455aa9 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/scripts/dependency/check_dependencies.sh @@ -0,0 +1,32 @@ +#!/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. +# + +BASE_PATH=$(cd "$(dirname "$0")" || exit; pwd) + +# check whether there are new third-party dependencies by diff command, +# diff generated 'current-dependencies.txt' file with 'known-dependencies.txt' file. +diff -w -B -U0 <(sort < "${BASE_PATH}"/known-dependencies.txt) \ + <(sort < "${BASE_PATH}"/current-dependencies.txt) > "${BASE_PATH}"/result.txt + +# if has new third-party,the Action will fail and print diff +if [ -s "${BASE_PATH}"/result.txt ]; then + cat "${BASE_PATH}"/result.txt + exit 1 +else + echo 'All third dependencies is known!' +fi diff --git a/hugegraph-commons/hugegraph-dist/scripts/dependency/known-dependencies.txt b/hugegraph-commons/hugegraph-dist/scripts/dependency/known-dependencies.txt new file mode 100644 index 0000000000..9a421edcd4 --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/scripts/dependency/known-dependencies.txt @@ -0,0 +1,45 @@ +annotations-13.0.jar +checker-qual-3.5.0.jar +commons-beanutils-1.9.4.jar +commons-codec-1.13.jar +commons-collections-3.2.2.jar +commons-configuration-1.10.jar +commons-configuration2-2.8.0.jar +commons-io-2.7.jar +commons-lang-2.6.jar +commons-lang3-3.12.0.jar +commons-logging-1.1.1.jar +commons-text-1.9.jar +error_prone_annotations-2.3.4.jar +failureaccess-1.0.1.jar +guava-30.0-jre.jar +hamcrest-core-1.3.jar +j2objc-annotations-1.3.jar +jackson-annotations-2.14.0-rc1.jar +jackson-core-2.14.0-rc1.jar +jackson-databind-2.14.0-rc1.jar +jackson-jaxrs-base-2.14.0-rc1.jar +jackson-jaxrs-json-provider-2.14.0-rc1.jar +jackson-module-jaxb-annotations-2.14.0-rc1.jar +jakarta.activation-2.0.1.jar +jakarta.activation-api-1.2.2.jar +javassist-3.28.0-GA.jar +javax.json-1.0.jar +jaxb-core-3.0.2.jar +jaxb-impl-3.0.2.jar +joda-time-2.10.8.jar +jsr305-3.0.1.jar +junit-4.13.1.jar +kotlin-stdlib-1.6.20.jar +kotlin-stdlib-common-1.5.31.jar +kotlin-stdlib-jdk7-1.6.10.jar +kotlin-stdlib-jdk8-1.6.10.jar +listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar +log4j-api-2.18.0.jar +log4j-core-2.18.0.jar +log4j-slf4j-impl-2.18.0.jar +logging-interceptor-4.10.0.jar +lombok-1.18.8.jar +okhttp-4.10.0.jar +okio-jvm-3.0.0.jar +slf4j-api-1.7.25.jar diff --git a/hugegraph-commons/hugegraph-dist/scripts/dependency/regenerate_known_dependencies.sh b/hugegraph-commons/hugegraph-dist/scripts/dependency/regenerate_known_dependencies.sh new file mode 100644 index 0000000000..91f8b986ad --- /dev/null +++ b/hugegraph-commons/hugegraph-dist/scripts/dependency/regenerate_known_dependencies.sh @@ -0,0 +1,33 @@ +#!/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. +# + +BASE_PATH=$(cd "$(dirname "$0")" || exit; pwd) +DEP_PATH=$BASE_PATH/all_dependencies +FILE_NAME=${1:-known-dependencies.txt} + +if [[ -d $DEP_PATH ]]; then + echo "rm -r -f DEP_PATH" + rm -r -f "$DEP_PATH" +fi + +cd "$BASE_PATH"/../../../ || exit + +mvn dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory="$DEP_PATH" + +ls "$DEP_PATH" | egrep -v "^hugegraph|hubble" | sort -n > "$BASE_PATH"/"$FILE_NAME" +rm -r -f "$DEP_PATH" diff --git a/hugegraph-commons/hugegraph-rpc/README.md b/hugegraph-commons/hugegraph-rpc/README.md new file mode 100644 index 0000000000..c316a9c412 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/README.md @@ -0,0 +1,14 @@ +# HugeGraph-RPC + +HugeGraph Database RPC component, currently it's based on [Sofa-RPC](https://github.com/sofastack/sofa-rpc) + +## Features + +## Learn More + +The [project homepage](https://hugegraph.github.io/hugegraph-doc/) contains more information on +HugeGraph and provides links to documentation, getting-started guides and release downloads. + +## License + +HugeGraph is licensed under Apache 2.0 License. diff --git a/hugegraph-commons/hugegraph-rpc/pom.xml b/hugegraph-commons/hugegraph-rpc/pom.xml new file mode 100644 index 0000000000..0637da1c5c --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/pom.xml @@ -0,0 +1,170 @@ + + + + 4.0.0 + + org.apache.hugegraph + hugegraph-commons + ${revision} + ../pom.xml + + + hugegraph-rpc + ${project.artifactId} + HugeGraph RPC component + + + + + + + + + org.apache.hugegraph + hugegraph-common + ${revision} + + + + + com.lmax + disruptor + 3.3.7 + + + com.alipay.sofa + bolt + 1.6.2 + + + org.slf4j + slf4j-api + + + + + com.alipay.sofa + sofa-rpc-all + 5.7.6 + + + org.jboss.resteasy + resteasy-client + + + org.jboss.resteasy + resteasy-netty4 + + + org.jboss.resteasy + resteasy-jackson2-provider + + + org.apache.httpcomponents + httpclient + + + org.apache.httpcomponents + httpcore + + + org.apache.httpcomponents + httpmime + + + org.jboss.logging + jboss-logging + + + org.slf4j + slf4j-api + + + io.grpc + grpc-core + + + + + io.grpc + grpc-core + 1.28.1 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.jacoco + jacoco-maven-plugin + 0.8.2 + + + pre-unit-test + + prepare-agent + + + + post-unit-test + test + + report + + + ${project.parent.build.directory} + + + + + + + + + + apache-release + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-gpg-plugin + + + + + + diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/config/RpcOptions.java b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/config/RpcOptions.java new file mode 100644 index 0000000000..09adcbab84 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/config/RpcOptions.java @@ -0,0 +1,158 @@ +/* + * 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 static org.apache.hugegraph.config.OptionChecker.allowValues; +import static org.apache.hugegraph.config.OptionChecker.disallowEmpty; +import static org.apache.hugegraph.config.OptionChecker.rangeInt; + +public class RpcOptions extends OptionHolder { + + private RpcOptions() { + super(); + } + + private static volatile RpcOptions instance; + + public static synchronized RpcOptions instance() { + if (instance == null) { + instance = new RpcOptions(); + instance.registerOptions(); + } + return instance; + } + + public static final ConfigOption RPC_SERVER_HOST = + new ConfigOption<>( + "rpc.server_host", + "The hosts/ips bound by rpc server to provide services, " + + "empty value means not enabled.", + null, + "" + ); + + public static final ConfigOption RPC_SERVER_PORT = + new ConfigOption<>( + "rpc.server_port", + "The port bound by rpc server to provide services.", + rangeInt(0, Integer.MAX_VALUE), + 8090 + ); + + public static final ConfigOption RPC_ADAPTIVE_PORT = + new ConfigOption<>( + "rpc.server_adaptive_port", + "Whether the bound port is adaptive, if it's enabled, " + + "when the port is in use, automatically +1 to detect " + + "the next available port. Note that this process is " + + "not atomic, so there may still be port conflicts.", + disallowEmpty(), + false + ); + + public static final ConfigOption RPC_SERVER_TIMEOUT = + new ConfigOption<>( + "rpc.server_timeout", + "The timeout(in seconds) of rpc server execution.", + rangeInt(1, Integer.MAX_VALUE), + 30 + ); + + public static final ConfigOption RPC_REMOTE_URL = + new ConfigOption<>( + "rpc.remote_url", + "The remote urls of rpc peers, it can be set to " + + "multiple addresses, which are concat by ',', " + + "empty value means not enabled.", + null, + "" + ); + + public static final ConfigOption RPC_CLIENT_CONNECT_TIMEOUT = + new ConfigOption<>( + "rpc.client_connect_timeout", + "The timeout(in seconds) of rpc client connect to rpc " + + "server.", + rangeInt(1, Integer.MAX_VALUE), + 20 + ); + + public static final ConfigOption RPC_CLIENT_RECONNECT_PERIOD = + new ConfigOption<>( + "rpc.client_reconnect_period", + "The period(in seconds) of rpc client reconnect to rpc " + + "server.", + rangeInt(1, Integer.MAX_VALUE), + 10 + ); + + public static final ConfigOption RPC_CLIENT_READ_TIMEOUT = + new ConfigOption<>( + "rpc.client_read_timeout", + "The timeout(in seconds) of rpc client read from rpc " + + "server.", + rangeInt(1, Integer.MAX_VALUE), + 40 + ); + + public static final ConfigOption RPC_CLIENT_RETRIES = + new ConfigOption<>( + "rpc.client_retries", + "Failed retry number of rpc client calls to rpc server.", + rangeInt(0, Integer.MAX_VALUE), + 3 + ); + + public static final ConfigOption RPC_CLIENT_LOAD_BALANCER = + new ConfigOption<>( + "rpc.client_load_balancer", + "The rpc client uses a load-balancing algorithm to " + + "access multiple rpc servers in one cluster. Default " + + "value is 'consistentHash', means forwarding by request " + + "parameters.", + allowValues("random", "localPref", "roundRobin", + "consistentHash", "weightRoundRobin"), + "consistentHash" + ); + + public static final ConfigOption RPC_PROTOCOL = + new ConfigOption<>( + "rpc.protocol", + "Rpc communication protocol, client and server need to " + + "be specified the same value.", + allowValues("bolt", "rest", "dubbo", "h2c", "http"), + "bolt" + ); + + public static final ConfigOption RPC_CONFIG_ORDER = + new ConfigOption<>( + "rpc.config_order", + "Sofa rpc configuration file loading order, the larger " + + "the more later loading.", + rangeInt(1, Integer.MAX_VALUE), + 999 + ); + + public static final ConfigOption RPC_LOGGER_IMPL = + new ConfigOption<>( + "rpc.logger_impl", + "Sofa rpc log implementation class.", + disallowEmpty(), + "com.alipay.sofa.rpc.log.SLF4JLoggerImpl" + ); +} diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcClientProvider.java b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcClientProvider.java new file mode 100644 index 0000000000..2b50468b9f --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcClientProvider.java @@ -0,0 +1,74 @@ +/* + * 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.rpc; + +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; + +import com.alipay.sofa.rpc.common.utils.StringUtils; +import org.apache.hugegraph.config.RpcOptions; +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.util.E; + +public class RpcClientProvider { + + private final RpcConsumerConfig consumerConfig; + + public RpcClientProvider(HugeConfig config) { + // TODO: fetch from registry server + String rpcUrl = config.get(RpcOptions.RPC_REMOTE_URL); + String selfUrl = config.get(RpcOptions.RPC_SERVER_HOST) + ":" + + config.get(RpcOptions.RPC_SERVER_PORT); + rpcUrl = excludeSelfUrl(rpcUrl, selfUrl); + this.consumerConfig = StringUtils.isNotBlank(rpcUrl) ? + new RpcConsumerConfig(config, rpcUrl) : null; + } + + public boolean enabled() { + return this.consumerConfig != null; + } + + public RpcConsumerConfig config() { + E.checkArgument(this.consumerConfig != null, + "RpcClient is not enabled, please config option '%s' " + + "and ensure to add an address other than self service", + RpcOptions.RPC_REMOTE_URL.name()); + return this.consumerConfig; + } + + public void unreferAll() { + if (this.consumerConfig != null) { + this.consumerConfig.removeAllServiceProxy(); + } + } + + public void destroy() { + if (this.consumerConfig != null) { + this.consumerConfig.destroy(); + } + } + + protected static String excludeSelfUrl(String rpcUrl, String selfUrl) { + String[] urls = StringUtils.splitWithCommaOrSemicolon(rpcUrl); + // Keep urls order via LinkedHashSet + Set urlSet = new LinkedHashSet<>(Arrays.asList(urls)); + urlSet.remove(selfUrl); + return String.join(",", urlSet); + } +} diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcCommonConfig.java b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcCommonConfig.java new file mode 100644 index 0000000000..37ec980302 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcCommonConfig.java @@ -0,0 +1,44 @@ +/* + * 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.rpc; + +import java.util.Map; + +import com.alipay.sofa.rpc.common.RpcConfigs; +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.config.RpcOptions; + +public class RpcCommonConfig { + + public static void initRpcConfigs(HugeConfig config) { + RpcConfigs.putValue("rpc.config.order", + config.get(RpcOptions.RPC_CONFIG_ORDER)); + RpcConfigs.putValue("logger.impl", + config.get(RpcOptions.RPC_LOGGER_IMPL)); + } + + public static void initRpcConfigs(String key, Object value) { + RpcConfigs.putValue(key, value); + } + + public static void initRpcConfigs(Map conf) { + for (Map.Entry entry : conf.entrySet()) { + RpcConfigs.putValue(entry.getKey(), entry.getValue()); + } + } +} diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcConsumerConfig.java b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcConsumerConfig.java new file mode 100644 index 0000000000..c489f5cd9b --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcConsumerConfig.java @@ -0,0 +1,215 @@ +/* + * 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.rpc; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; + +import com.alipay.sofa.rpc.bootstrap.Bootstraps; +import com.alipay.sofa.rpc.bootstrap.ConsumerBootstrap; +import com.alipay.sofa.rpc.client.AbstractCluster; +import com.alipay.sofa.rpc.client.Cluster; +import com.alipay.sofa.rpc.client.ProviderInfo; +import com.alipay.sofa.rpc.config.ConsumerConfig; +import com.alipay.sofa.rpc.core.exception.RpcErrorType; +import com.alipay.sofa.rpc.core.exception.SofaRpcException; +import com.alipay.sofa.rpc.core.request.SofaRequest; +import com.alipay.sofa.rpc.core.response.SofaResponse; +import com.alipay.sofa.rpc.ext.Extension; +import com.alipay.sofa.rpc.ext.ExtensionLoaderFactory; +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.config.RpcOptions; +import org.apache.hugegraph.util.Log; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public class RpcConsumerConfig implements RpcServiceConfig4Client { + + private final HugeConfig conf; + private final String remoteUrls; + private final Map> configs; + private final List> bootstraps; + + static { + ExtensionLoaderFactory.getExtensionLoader(Cluster.class) + .loadExtension(FanoutCluster.class); + } + + public RpcConsumerConfig(HugeConfig config, String remoteUrls) { + RpcCommonConfig.initRpcConfigs(config); + this.conf = config; + this.remoteUrls = remoteUrls; + this.configs = Maps.newHashMap(); + this.bootstraps = Lists.newArrayList(); + } + + @Override + public T serviceProxy(String interfaceId) { + return this.serviceProxy(null, interfaceId); + } + + @Override + public T serviceProxy(String graph, String interfaceId) { + ConsumerConfig config = this.consumerConfig(graph, interfaceId); + ConsumerBootstrap bootstrap = Bootstraps.from(config); + this.bootstraps.add(bootstrap); + return bootstrap.refer(); + } + + @Override + public void removeAllServiceProxy() { + for (ConsumerBootstrap bootstrap : this.bootstraps) { + bootstrap.unRefer(); + } + } + + public void destroy() { + Set clusters = Sets.newHashSet(); + for (ConsumerBootstrap bootstrap : this.bootstraps) { + bootstrap.unRefer(); + clusters.add(bootstrap.getCluster()); + } + for (Cluster cluster : clusters) { + cluster.destroy(); + } + } + + private ConsumerConfig consumerConfig(String graph, + String interfaceId) { + String serviceId; + if (graph != null) { + serviceId = interfaceId + ":" + graph; + } else { + serviceId = interfaceId; + } + + @SuppressWarnings("unchecked") + ConsumerConfig consumerConfig = (ConsumerConfig) + this.configs.get(serviceId); + if (consumerConfig != null) { + return consumerConfig; + } + + assert consumerConfig == null; + consumerConfig = new ConsumerConfig<>(); + + HugeConfig conf = this.conf; + String protocol = conf.get(RpcOptions.RPC_PROTOCOL); + int timeout = conf.get(RpcOptions.RPC_CLIENT_READ_TIMEOUT) * 1000; + int connectTimeout = conf.get(RpcOptions + .RPC_CLIENT_CONNECT_TIMEOUT) * 1000; + int reconnectPeriod = conf.get(RpcOptions + .RPC_CLIENT_RECONNECT_PERIOD) * 1000; + int retries = conf.get(RpcOptions.RPC_CLIENT_RETRIES); + String loadBalancer = conf.get(RpcOptions.RPC_CLIENT_LOAD_BALANCER); + + if (graph != null) { + consumerConfig.setId(serviceId).setUniqueId(graph); + // Default is FailoverCluster, set to FanoutCluster to broadcast + consumerConfig.setCluster("fanout"); + } + consumerConfig.setInterfaceId(interfaceId) + .setProtocol(protocol) + .setDirectUrl(this.remoteUrls) + .setTimeout(timeout) + .setConnectTimeout(connectTimeout) + .setReconnectPeriod(reconnectPeriod) + .setRetries(retries) + .setLoadBalancer(loadBalancer); + + this.configs.put(serviceId, consumerConfig); + return consumerConfig; + } + + @Extension("fanout") + private static class FanoutCluster extends AbstractCluster { + + private static final Logger LOG = Log.logger(FanoutCluster.class); + + FanoutCluster(ConsumerBootstrap consumerBootstrap) { + super(consumerBootstrap); + } + + @Override + protected SofaResponse doInvoke(SofaRequest request) + throws SofaRpcException { + List providers = this.getRouterChain() + .route(request, null); + List responses = new ArrayList<>(providers.size()); + List excepts = new ArrayList<>(providers.size()); + + for (ProviderInfo provider : providers) { + try { + SofaResponse response = this.doInvoke(request, provider); + responses.add(response); + } catch (SofaRpcException e) { + excepts.add(e); + LOG.warn("{}.(error {})", e.getMessage(), e.getErrorType()); + } + } + + if (responses.size() > 0) { + /* + * Just choose the first one as result to return, ignore others + * TODO: maybe more strategies should be provided + */ + return responses.get(0); + } else if (excepts.size() > 0) { + throw excepts.get(0); + } else { + assert providers.isEmpty(); + String method = methodName(request); + throw new SofaRpcException(RpcErrorType.CLIENT_ROUTER, + "No service provider for " + method); + } + } + + private SofaResponse doInvoke(SofaRequest request, + ProviderInfo providerInfo) { + try { + SofaResponse response = this.filterChain(providerInfo, request); + if (response != null) { + return response; + } + String method = methodName(request); + throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, + "Failed to call " + method + " on remote server " + + providerInfo + ", return null response"); + } catch (Exception e) { + int error = RpcErrorType.CLIENT_UNDECLARED_ERROR; + if (e instanceof SofaRpcException) { + error = ((SofaRpcException) e).getErrorType(); + } + String method = methodName(request); + throw new SofaRpcException(error, + "Failed to call " + method + " on remote server " + + providerInfo + ", caused by exception: " + e); + } + } + + private static String methodName(SofaRequest request) { + return request.getInterfaceName() + "." + + request.getMethodName() + "()"; + } + } +} diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcException.java b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcException.java new file mode 100644 index 0000000000..59e80f3d53 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcException.java @@ -0,0 +1,39 @@ +/* + * 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.rpc; + +public class RpcException extends RuntimeException { + + private static final long serialVersionUID = -6067652498161184537L; + + public RpcException(String message) { + super(message); + } + + public RpcException(String message, Throwable cause) { + super(message, cause); + } + + public RpcException(String message, Object... args) { + super(String.format(message, args)); + } + + public RpcException(String message, Throwable cause, Object... args) { + super(String.format(message, args), cause); + } +} diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcProviderConfig.java b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcProviderConfig.java new file mode 100644 index 0000000000..dafdfcf5a4 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcProviderConfig.java @@ -0,0 +1,83 @@ +/* + * 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.rpc; + +import java.util.Map; + +import com.alipay.sofa.rpc.config.ProviderConfig; +import org.apache.hugegraph.util.E; +import com.google.common.collect.Maps; + +public class RpcProviderConfig implements RpcServiceConfig4Server { + + private final Map> configs = Maps.newHashMap(); + + @Override + public String addService(Class clazz, S serviceImpl) { + return this.addService(null, clazz.getName(), serviceImpl); + } + + @Override + public String addService(String graph, + Class clazz, + S serviceImpl) { + return this.addService(graph, clazz.getName(), serviceImpl); + } + + private String addService(String graph, + String interfaceId, + S serviceImpl) { + ProviderConfig providerConfig = new ProviderConfig<>(); + String serviceId; + if (graph != null) { + serviceId = interfaceId + ":" + graph; + providerConfig.setId(serviceId).setUniqueId(graph); + } else { + serviceId = interfaceId; + } + + providerConfig.setInterfaceId(interfaceId) + .setRef(serviceImpl); + + E.checkArgument(!this.configs.containsKey(serviceId), + "Not allowed to add service already exist: '%s'", + serviceId); + this.configs.put(serviceId, providerConfig); + return serviceId; + } + + @Override + public void removeService(String serviceId) { + ProviderConfig config = this.configs.remove(serviceId); + E.checkArgument(config != null, + "The service '%s' doesn't exist", serviceId); + config.unExport(); + } + + @Override + public void removeAllService() { + for (ProviderConfig config : this.configs.values()) { + config.unExport(); + } + this.configs.clear(); + } + + public Map> configs() { + return this.configs; + } +} diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServer.java b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServer.java new file mode 100644 index 0000000000..fe0b91ac58 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServer.java @@ -0,0 +1,147 @@ +/* + * 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.rpc; + +import java.util.Map; + +import org.slf4j.Logger; + +import com.alipay.remoting.RemotingServer; +import com.alipay.sofa.rpc.common.utils.StringUtils; +import com.alipay.sofa.rpc.config.ProviderConfig; +import com.alipay.sofa.rpc.config.ServerConfig; +import com.alipay.sofa.rpc.server.Server; +import com.alipay.sofa.rpc.server.bolt.BoltServer; +import org.apache.hugegraph.config.RpcOptions; +import org.apache.commons.collections.MapUtils; +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.testutil.Whitebox; +import org.apache.hugegraph.util.E; +import org.apache.hugegraph.util.Log; + +public class RpcServer { + + private static final Logger LOG = Log.logger(RpcServer.class); + + private final HugeConfig conf; + private final RpcProviderConfig configs; + private final ServerConfig serverConfig; + + public RpcServer(HugeConfig config) { + RpcCommonConfig.initRpcConfigs(config); + this.conf = config; + this.configs = new RpcProviderConfig(); + + String host = config.get(RpcOptions.RPC_SERVER_HOST); + if (StringUtils.isNotBlank(host)) { + int port = config.get(RpcOptions.RPC_SERVER_PORT); + boolean adaptivePort = config.get(RpcOptions.RPC_ADAPTIVE_PORT); + this.serverConfig = new ServerConfig(); + this.serverConfig.setProtocol(config.get(RpcOptions.RPC_PROTOCOL)) + .setHost(host).setPort(port) + .setAdaptivePort(adaptivePort) + .setDaemon(false); + } else { + this.serverConfig = null; + } + } + + public boolean enabled() { + return this.serverConfig != null; + } + + public RpcProviderConfig config() { + this.checkEnabled(); + return this.configs; + } + + public String host() { + this.checkEnabled(); + return this.serverConfig.getBoundHost(); + } + + public int port() { + this.checkEnabled(); + Server server = this.serverConfig.getServer(); + if (server instanceof BoltServer && server.isStarted()) { + /* + * When using random port 0, try to fetch the actual port + * NOTE: RemotingServer.port() would return the actual port only + * if sofa-bolt version >= 1.6.1, please see: + * https://github.com/sofastack/sofa-bolt/issues/196 + * TODO: remove this code after adding Server.port() interface: + * https://github.com/sofastack/sofa-rpc/issues/1022 + */ + RemotingServer rs = Whitebox.getInternalState(server, + "remotingServer"); + return rs.port(); + } + // When using random port 0, the returned port is not the actual port + return this.serverConfig.getPort(); + } + + public void exportAll() { + this.checkEnabled(); + LOG.debug("RpcServer starting on port {}", this.port()); + Map> configs = this.configs.configs(); + if (MapUtils.isEmpty(configs)) { + LOG.info("RpcServer config is empty, skip starting RpcServer"); + return; + } + int timeout = this.conf.get(RpcOptions.RPC_SERVER_TIMEOUT) * 1000; + for (ProviderConfig providerConfig : configs.values()) { + providerConfig.setServer(this.serverConfig) + .setTimeout(timeout) + .export(); + } + LOG.info("RpcServer started success on port {}", this.port()); + } + + public void unexportAll() { + this.configs.removeAllService(); + } + + public void unexport(String serviceId) { + this.configs.removeService(serviceId); + } + + public void destroy() { + if (!this.enabled()) { + return; + } + LOG.info("RpcServer stop on port {}", this.port()); + for (ProviderConfig config : this.configs.configs().values()) { + Object service = config.getRef(); + if (service instanceof AutoCloseable) { + try { + ((AutoCloseable) service).close(); + } catch (Exception e) { + LOG.warn("Failed to close service {}", service, e); + } + } + } + this.serverConfig.destroy(); + this.configs.removeAllService(); + } + + private void checkEnabled() { + E.checkArgument(this.enabled(), + "RpcServer is not enabled, please config option '%s'", + RpcOptions.RPC_SERVER_HOST.name()); + } +} diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Client.java b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Client.java new file mode 100644 index 0000000000..b08d6327d1 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Client.java @@ -0,0 +1,35 @@ +/* + * 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.rpc; + +public interface RpcServiceConfig4Client { + + T serviceProxy(String interfaceId); + + T serviceProxy(String graph, String interfaceId); + + default T serviceProxy(Class clazz) { + return this.serviceProxy(clazz.getName()); + } + + default T serviceProxy(String graph, Class clazz) { + return this.serviceProxy(graph, clazz.getName()); + } + + void removeAllServiceProxy(); +} diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Server.java b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Server.java new file mode 100644 index 0000000000..cd0290900e --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/rpc/RpcServiceConfig4Server.java @@ -0,0 +1,29 @@ +/* + * 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.rpc; + +public interface RpcServiceConfig4Server { + + String addService(Class clazz, S serviceImpl); + + String addService(String graph, Class clazz, S serviceImpl); + + void removeService(String serviceId); + + void removeAllService(); +} diff --git a/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/version/RpcVersion.java b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/version/RpcVersion.java new file mode 100644 index 0000000000..a2dd3d72c1 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/main/java/org/apache/hugegraph/version/RpcVersion.java @@ -0,0 +1,28 @@ +/* + * 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.version; + +import org.apache.hugegraph.util.VersionUtil.Version; + +public class RpcVersion { + + public static final String NAME = "hugegraph-rpc"; + + // The second parameter of Version.of() is for all-in-one JAR + public static final Version VERSION = Version.of(RpcVersion.class, "1.5.0"); +} diff --git a/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/BaseUnitTest.java b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/BaseUnitTest.java new file mode 100644 index 0000000000..919ba151f0 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/BaseUnitTest.java @@ -0,0 +1,56 @@ +/* + * 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.unit; + +import java.net.URL; + +import org.junit.BeforeClass; + +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.config.OptionSpace; +import org.apache.hugegraph.rpc.RpcServer; + +public class BaseUnitTest { + + @BeforeClass + public static void initEnv() { + OptionSpace.register("rpc", "org.apache.hugegraph.config.RpcOptions"); + } + + protected static HugeConfig config(boolean server) { + return config(server ? "server" : "client"); + } + + protected static HugeConfig config(String type) { + String name = String.format("rpc-%s.properties", type); + URL conf = BaseUnitTest.class.getClassLoader().getResource(name); + return new HugeConfig(conf.getPath()); + } + + protected static void startServer(RpcServer rpcServer) { + rpcServer.config().configs().values().forEach(c -> { + c.setRepeatedExportLimit(100); + }); + + rpcServer.exportAll(); + } + + protected static void stopServer(RpcServer rpcServer) { + rpcServer.destroy(); + } +} diff --git a/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/ExceptionTest.java b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/ExceptionTest.java new file mode 100644 index 0000000000..ae5f2edc43 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/ExceptionTest.java @@ -0,0 +1,56 @@ +/* + * 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.unit; + +import org.junit.Test; + +import org.apache.hugegraph.rpc.RpcException; +import org.apache.hugegraph.testutil.Assert; + +public class ExceptionTest { + + @Test + public void testExceptionWithMessage() { + RpcException e = new RpcException("test"); + Assert.assertEquals("test", e.getMessage()); + Assert.assertNull(e.getCause()); + } + + @Test + public void testExceptionWithMessageAndCause() { + Exception cause = new Exception(); + RpcException e = new RpcException("test", cause); + Assert.assertEquals("test", e.getMessage()); + Assert.assertEquals(cause, e.getCause()); + } + + @Test + public void testExceptionWithMessageAndArgs() { + RpcException e = new RpcException("test %s", 168); + Assert.assertEquals("test 168", e.getMessage()); + Assert.assertNull(e.getCause()); + } + + @Test + public void testExceptionWithMessageAndArgsAndCause() { + Exception cause = new Exception(); + RpcException e = new RpcException("test %s", cause, 168); + Assert.assertEquals("test 168", e.getMessage()); + Assert.assertEquals(cause, e.getCause()); + } +} diff --git a/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/ServerClientTest.java b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/ServerClientTest.java new file mode 100644 index 0000000000..6b800c02c2 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/ServerClientTest.java @@ -0,0 +1,778 @@ +/* + * 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.unit; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.alipay.sofa.rpc.common.RpcOptions; +import com.alipay.sofa.rpc.core.exception.SofaRpcException; +import com.alipay.sofa.rpc.core.exception.SofaRpcRuntimeException; +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.rpc.RpcClientProvider; +import org.apache.hugegraph.rpc.RpcCommonConfig; +import org.apache.hugegraph.rpc.RpcConsumerConfig; +import org.apache.hugegraph.rpc.RpcProviderConfig; +import org.apache.hugegraph.rpc.RpcServer; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.testutil.Whitebox; +import org.apache.hugegraph.util.E; +import com.google.common.collect.ImmutableMap; + +public class ServerClientTest extends BaseUnitTest { + + private static RpcServer rpcServer; + private static RpcClientProvider rpcClient; + + @BeforeClass + public static void init() { + rpcServer = new RpcServer(config(true)); + rpcClient = new RpcClientProvider(config(false)); + } + + @AfterClass + public static void clear() { + if (rpcClient != null) { + rpcClient.destroy(); + } + if (rpcServer != null) { + rpcServer.destroy(); + } + } + + @After + public void teardown() { + if (rpcClient != null) { + rpcClient.unreferAll(); + } + if (rpcServer != null) { + rpcServer.unexportAll(); + } + } + + @Test + public void testSimpleService() { + // Init server + RpcProviderConfig serverConfig = rpcServer.config(); + serverConfig.addService(HelloService.class, new HelloServiceImpl()); + startServer(rpcServer); + + // Init client + RpcConsumerConfig clientConfig = rpcClient.config(); + HelloService client = clientConfig.serviceProxy(HelloService.class); + + // Test call + Assert.assertEquals("hello tom!", client.hello("tom")); + Assert.assertEquals("tom", client.echo("tom")); + Assert.assertEquals(5.14, client.sum(2, 3.14), 0.00000001d); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + client.hello(""); + }, e -> { + Assert.assertContains("empty hello parameter", e.getMessage()); + }); + } + + @Test + public void testMultiService() { + // Init server + GraphHelloServiceImpl g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl g2 = new GraphHelloServiceImpl("g2"); + GraphHelloServiceImpl g3 = new GraphHelloServiceImpl("g3"); + + RpcProviderConfig serverConfig = rpcServer.config(); + serverConfig.addService(g1.graph(), HelloService.class, g1); + serverConfig.addService(g2.graph(), HelloService.class, g2); + serverConfig.addService(g3.graph(), HelloService.class, g3); + startServer(rpcServer); + + // Init client + RpcConsumerConfig clientConfig = rpcClient.config(); + HelloService c1 = clientConfig.serviceProxy("g1", HelloService.class); + HelloService c2 = clientConfig.serviceProxy("g2", HelloService.class); + HelloService c3 = clientConfig.serviceProxy("g3", HelloService.class); + + // Test call + Assert.assertEquals("g1: hello tom!", c1.hello("tom")); + Assert.assertEquals("g1: tom", c1.echo("tom")); + Assert.assertEquals(5.14, c1.sum(2, 3.14), 0.00000001d); + + Assert.assertEquals("g2: hello tom!", c2.hello("tom")); + Assert.assertEquals("g2: tom", c2.echo("tom")); + Assert.assertEquals(6.14, c2.sum(3, 3.14), 0.00000001d); + + Assert.assertEquals("g3: hello tom!", c3.hello("tom")); + Assert.assertEquals("g3: tom", c3.echo("tom")); + Assert.assertEquals(103.14, c3.sum(100, 3.14), 0.00000001d); + + Assert.assertEquals(5.14, g1.result(), 0.00000001d); + Assert.assertEquals(6.14, g2.result(), 0.00000001d); + Assert.assertEquals(103.14, g3.result(), 0.00000001d); + } + + @Test + public void testStartServerWithRandomPort() { + // Init server + RpcServer rpcServerRandom = new RpcServer(config("server-random")); + RpcProviderConfig serverConfig = rpcServerRandom.config(); + serverConfig.addService(HelloService.class, new HelloServiceImpl()); + startServer(rpcServerRandom); + + Assert.assertNotEquals(0, rpcServerRandom.port()); + Assert.assertNotEquals(8090, rpcServerRandom.port()); + + // Init client + HugeConfig config = config(false); + String url = rpcServerRandom.host() + ":" + rpcServerRandom.port(); + String remoteUrlKey = org.apache.hugegraph.config.RpcOptions.RPC_REMOTE_URL.name(); + config.setProperty(remoteUrlKey, url); + RpcClientProvider rpcClientRandom = new RpcClientProvider(config); + + RpcConsumerConfig clientConfig = rpcClientRandom.config(); + HelloService client = clientConfig.serviceProxy(HelloService.class); + + // Test call + Assert.assertEquals("hello tom!", client.hello("tom")); + Assert.assertEquals("tom", client.echo("tom")); + Assert.assertEquals(5.14, client.sum(2, 3.14), 0.00000001d); + + // Destroy all + rpcClientRandom.destroy(); + stopServer(rpcServerRandom); + } + + @Test + public void testStartServerWithAdaptivePort() throws IOException { + // Init server + RpcServer rpcServerAdaptive = new RpcServer(config("server-adaptive")); + RpcProviderConfig serverConfig = rpcServerAdaptive.config(); + serverConfig.addService(HelloService.class, new HelloServiceImpl()); + + // Start other server bound the port + int usedPort = rpcServerAdaptive.port(); + InetAddress ip = InetAddress.getByName(rpcServerAdaptive.host()); + ServerSocket inUse = new ServerSocket(usedPort,50, ip); + + // Start server after the port in use + startServer(rpcServerAdaptive); + + Assert.assertNotEquals(0, rpcServerAdaptive.port()); + Assert.assertNotEquals(usedPort, rpcServerAdaptive.port()); + + // Init client + HugeConfig config = config(false); + String url = rpcServerAdaptive.host() + ":" + rpcServerAdaptive.port(); + String remoteUrlKey = org.apache.hugegraph.config.RpcOptions.RPC_REMOTE_URL.name(); + config.setProperty(remoteUrlKey, url); + RpcClientProvider rpcClientAdaptive = new RpcClientProvider(config); + + RpcConsumerConfig clientConfig = rpcClientAdaptive.config(); + HelloService client = clientConfig.serviceProxy(HelloService.class); + + // Test call + Assert.assertEquals("hello tom!", client.hello("tom")); + Assert.assertEquals("tom", client.echo("tom")); + Assert.assertEquals(5.14, client.sum(2, 3.14), 0.00000001d); + + // Destroy all + rpcClientAdaptive.destroy(); + stopServer(rpcServerAdaptive); + + inUse.close(); + } + + @Test + public void testStartBothServerAndClientThroughSameConfig() { + // Init server1 + HugeConfig server1 = config("server1-client"); + RpcServer rpcServer1 = new RpcServer(server1); + RpcClientProvider rpcClient1 = new RpcClientProvider(server1); + + GraphHelloServiceImpl s1g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl s1g2 = new GraphHelloServiceImpl("g2"); + + rpcServer1.config().addService(s1g1.graph(), HelloService.class, s1g1); + rpcServer1.config().addService(s1g2.graph(), HelloService.class, s1g2); + + startServer(rpcServer1); + + // Init server2 + HugeConfig server2 = config("server2-client"); + RpcServer rpcServer2 = new RpcServer(server2); + RpcClientProvider rpcClient2 = new RpcClientProvider(server2); + + GraphHelloServiceImpl s2g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl s2g2 = new GraphHelloServiceImpl("g2"); + + rpcServer2.config().addService(s2g1.graph(), HelloService.class, s2g1); + rpcServer2.config().addService(s2g2.graph(), HelloService.class, s2g2); + + startServer(rpcServer2); + + // Init client1 + HelloService s2g1Client = rpcClient1.config().serviceProxy( + "g1", HelloService.class); + HelloService s2g2Client = rpcClient1.config().serviceProxy( + "g2", HelloService.class); + + // Init client2 + HelloService s1g1Client = rpcClient2.config().serviceProxy( + "g1", HelloService.class); + HelloService s1g2Client = rpcClient2.config().serviceProxy( + "g2", HelloService.class); + + // Test call + Assert.assertEquals(2.1, s2g1Client.sum(1, 1.1), 0.00000001d); + Assert.assertEquals(2.2, s2g2Client.sum(1, 1.2), 0.00000001d); + + Assert.assertEquals(1.1, s1g1Client.sum(1, 0.1), 0.00000001d); + Assert.assertEquals(1.2, s1g2Client.sum(0, 1.2), 0.00000001d); + + Assert.assertEquals(1.1, s1g1.result(), 0.00000001d); + Assert.assertEquals(1.2, s1g2.result(), 0.00000001d); + Assert.assertEquals(2.1, s2g1.result(), 0.00000001d); + Assert.assertEquals(2.2, s2g2.result(), 0.00000001d); + + // Destroy all + rpcClient1.destroy(); + rpcClient2.destroy(); + stopServer(rpcServer1); + stopServer(rpcServer2); + } + + @Test + public void testFanoutCallService() { + // Init 3 servers + HugeConfig server3 = config("server3"); + RpcServer rpcServer3 = new RpcServer(server3); + + HugeConfig server4 = config("server4"); + RpcServer rpcServer4 = new RpcServer(server4); + + HugeConfig server5 = config("server5"); + RpcServer rpcServer5 = new RpcServer(server5); + + GraphHelloServiceImpl s3g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl s4g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl s5g1 = new GraphHelloServiceImpl("g1"); + + rpcServer3.config().addService(s3g1.graph(), HelloService.class, s3g1); + rpcServer4.config().addService(s4g1.graph(), HelloService.class, s4g1); + rpcServer5.config().addService(s5g1.graph(), HelloService.class, s5g1); + + startServer(rpcServer3); + startServer(rpcServer4); + startServer(rpcServer5); + + // Init client + HugeConfig client345 = config("client345"); + RpcClientProvider rpcClient345 = new RpcClientProvider(client345); + + HelloService g1 = rpcClient345.config() + .serviceProxy("g1", HelloService.class); + + // Test fanout + Assert.assertEquals("g1: fanout", g1.echo("fanout")); + Assert.assertEquals(16.8, g1.sum(10, 6.8), 0.00000001d); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + g1.hello(""); + }, e -> { + Assert.assertContains("empty hello parameter", e.getMessage()); + }); + + Assert.assertEquals(16.8, s3g1.result(), 0.00000001d); + Assert.assertEquals(16.8, s4g1.result(), 0.00000001d); + Assert.assertEquals(16.8, s5g1.result(), 0.00000001d); + + // Destroy all + rpcClient345.destroy(); + + stopServer(rpcServer3); + stopServer(rpcServer4); + stopServer(rpcServer5); + } + + @Test + public void testFanoutCallServiceWithError() { + // Init 3 servers + HugeConfig server3 = config("server3"); + RpcServer rpcServer3 = new RpcServer(server3); + + HugeConfig server4 = config("server4"); + RpcServer rpcServer4 = new RpcServer(server4); + + HugeConfig server5 = config("server5"); + RpcServer rpcServer5 = new RpcServer(server5); + + GraphHelloServiceImpl s3g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl s4g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl s5g1 = new GraphHelloServiceImpl("g1"); + + rpcServer3.config().addService(s3g1.graph(), HelloService.class, s3g1); + rpcServer4.config().addService(s4g1.graph(), HelloService.class, s4g1); + rpcServer5.config().addService(s5g1.graph(), HelloService.class, s5g1); + + startServer(rpcServer3); + startServer(rpcServer4); + startServer(rpcServer5); + + // Init client with one server unavailable + HugeConfig client346 = config("client346"); + RpcClientProvider rpcClient346 = new RpcClientProvider(client346); + + HelloService g1 = rpcClient346.config() + .serviceProxy("g1", HelloService.class); + + // Test fanout with one failed + Assert.assertEquals("g1: fanout", g1.echo("fanout")); + Assert.assertEquals(16.8, g1.sum(10, 6.8), 0.00000001d); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + g1.hello(""); + }, e -> { + Assert.assertContains("empty hello parameter", e.getMessage()); + }); + + Assert.assertEquals(16.8, s3g1.result(), 0.00000001d); + Assert.assertEquals(16.8, s4g1.result(), 0.00000001d); + Assert.assertEquals(0.0, s5g1.result(), 0.00000001d); + + s3g1.resetResult(); + s4g1.resetResult(); + s5g1.resetResult(); + + // Init client with all servers unavailable + HugeConfig client67 = config("client67"); + RpcClientProvider rpcClient67 = new RpcClientProvider(client67); + + HelloService g67 = rpcClient67.config() + .serviceProxy("g1", HelloService.class); + + // Test fanout with all failed + Assert.assertThrows(SofaRpcException.class, () -> { + g67.echo("fanout"); + }, e -> { + Assert.assertContains("Failed to call", e.getMessage()); + Assert.assertContains("echo() on remote server", e.getMessage()); + }); + + Assert.assertEquals(0.0, s3g1.result(), 0.00000001d); + Assert.assertEquals(0.0, s4g1.result(), 0.00000001d); + Assert.assertEquals(0.0, s5g1.result(), 0.00000001d); + + // Init client with none service provider + RpcClientProvider rpcClient0 = new RpcClientProvider(client67); + Whitebox.setInternalState(rpcClient0, "consumerConfig.remoteUrls", + ""); + HelloService g0 = rpcClient0.config() + .serviceProxy("g1", HelloService.class); + + Assert.assertThrows(SofaRpcException.class, () -> { + g0.echo("fanout"); + }, e -> { + Assert.assertContains("No service provider for", e.getMessage()); + }); + + // Destroy all + rpcClient346.destroy(); + rpcClient67.destroy(); + + stopServer(rpcServer3); + stopServer(rpcServer4); + stopServer(rpcServer5); + } + + @Test + public void testLoadBalancer() { + // Init 3 servers + HugeConfig server3 = config("server3"); + RpcServer rpcServer3 = new RpcServer(server3); + + HugeConfig server4 = config("server4"); + RpcServer rpcServer4 = new RpcServer(server4); + + HugeConfig server5 = config("server5"); + RpcServer rpcServer5 = new RpcServer(server5); + + GraphHelloServiceImpl s3g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl s4g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl s5g1 = new GraphHelloServiceImpl("g1"); + + rpcServer3.config().addService(HelloService.class, s3g1); + rpcServer4.config().addService(HelloService.class, s4g1); + rpcServer5.config().addService(HelloService.class, s5g1); + + startServer(rpcServer3); + startServer(rpcServer4); + startServer(rpcServer5); + + // Test LB "consistentHash" + HugeConfig clientLB = config("client-lb"); + RpcClientProvider rpcClientCHash = new RpcClientProvider(clientLB); + HelloService cHash = rpcClientCHash.config() + .serviceProxy(HelloService.class); + + Assert.assertEquals("g1: load", cHash.echo("load")); + Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d); + Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + Assert.assertEquals("g1: load", cHash.echo("load")); + Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d); + Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + Assert.assertEquals("g1: load", cHash.echo("load")); + Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d); + Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + s3g1.resetResult(); + s4g1.resetResult(); + s5g1.resetResult(); + + // Test LB "roundRobin" + String lbKey = org.apache.hugegraph.config.RpcOptions.RPC_CLIENT_LOAD_BALANCER.name(); + clientLB.setProperty(lbKey, "roundRobin"); + RpcClientProvider rpcClientRound = new RpcClientProvider(clientLB); + HelloService round = rpcClientRound.config() + .serviceProxy(HelloService.class); + + Assert.assertEquals("g1: load", round.echo("load")); + Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d); + Assert.assertEquals(1.1, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + Assert.assertEquals("g1: load", round.echo("load")); + Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d); + Assert.assertEquals(2.2, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + Assert.assertEquals("g1: load", round.echo("load")); + Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d); + Assert.assertEquals(3.3, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + s3g1.resetResult(); + s4g1.resetResult(); + s5g1.resetResult(); + + // Test LB "random" + clientLB.setProperty(lbKey, "random"); + RpcClientProvider rpcClientRandom = new RpcClientProvider(clientLB); + HelloService random = rpcClientRandom.config() + .serviceProxy(HelloService.class); + + Assert.assertEquals("g1: load", random.echo("load")); + Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d); + Assert.assertEquals(1.1, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + Assert.assertEquals("g1: load", random.echo("load")); + Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d); + double sum = s3g1.result() + s4g1.result() + s5g1.result(); + Assert.assertTrue(2.2 == sum || 1.1 == sum); + + Assert.assertEquals("g1: load", random.echo("load")); + Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d); + double sum2 = s3g1.result() + s4g1.result() + s5g1.result(); + Assert.assertTrue(sum == sum2 || sum + 1.1 == sum2); + + for (int i = 0; i < 9; i++) { + Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d); + } + Assert.assertEquals(3.3, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + s3g1.resetResult(); + s4g1.resetResult(); + s5g1.resetResult(); + + // Destroy all + rpcClientCHash.destroy(); + rpcClientRound.destroy(); + rpcClientRandom.destroy(); + + stopServer(rpcServer3); + stopServer(rpcServer4); + stopServer(rpcServer5); + } + + @Test + public void testServiceProxy() { + // Init server + RpcProviderConfig serverConfig = rpcServer.config(); + serverConfig.addService(HelloService.class, new HelloServiceImpl()); + serverConfig.addService("graph", HelloService.class, + new GraphHelloServiceImpl("graph")); + startServer(rpcServer); + + // Init client + RpcConsumerConfig clientConfig = rpcClient.config(); + HelloService client = clientConfig.serviceProxy(HelloService.class); + HelloService client2 = clientConfig.serviceProxy(HelloService.class); + HelloService clientG = clientConfig.serviceProxy("graph", + HelloService.class); + + // Test call + Assert.assertNotEquals(client, client2); + Assert.assertEquals("hello tom!", client.hello("tom")); + Assert.assertEquals("hello tom!", client2.hello("tom")); + Assert.assertEquals("graph: hello tom!", clientG.hello("tom")); + + // Test call after unrefer + rpcClient.unreferAll(); + + Assert.assertThrows(SofaRpcRuntimeException.class, () -> { + client.hello("tom"); + }); + Assert.assertThrows(SofaRpcRuntimeException.class, () -> { + client2.hello("tom"); + }); + Assert.assertThrows(SofaRpcRuntimeException.class, () -> { + clientG.hello("tom"); + }); + } + + @Test + public void testAddServiceMultiTimesOfSameService() { + RpcServer rpcServerExport = new RpcServer(config(true)); + + rpcServerExport.config().addService(HelloService.class, + new HelloServiceImpl()); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + rpcServerExport.config().addService(HelloService.class, + new HelloServiceImpl()); + }, e -> { + Assert.assertContains("Not allowed to add service already exist", + e.getMessage()); + }); + + rpcServerExport.exportAll(); + + stopServer(rpcServerExport); + } + + @Test + public void testExportMultiTimesOfSameServer() { + RpcServer rpcServerExport = new RpcServer(config(true)); + rpcServerExport.config().addService(HelloService.class, + new HelloServiceImpl()); + rpcServerExport.exportAll(); + rpcServerExport.exportAll(); + + stopServer(rpcServerExport); + } + + @Test + public void testExportMultiTimesOfSameService() { + RpcServer rpcServerExport = new RpcServer(config(true)); + rpcServerExport.config().addService(HelloService.class, + new HelloServiceImpl()); + rpcServerExport.exportAll(); + + rpcServerExport.config().addService("graph", HelloService.class, + new HelloServiceImpl()); + rpcServerExport.exportAll(); + + stopServer(rpcServerExport); + } + + @Test + public void testExportNoneService() { + RpcServer rpcServerNoneService = new RpcServer(config(true)); + + // Will be ignored if none service added + rpcServerNoneService.exportAll(); + + stopServer(rpcServerNoneService); + } + + @Test + public void testUnexportService() { + RpcServer rpcServerUnexport = new RpcServer(config(true)); + + RpcProviderConfig serverConfig = rpcServerUnexport.config(); + String service = serverConfig.addService(HelloService.class, + new HelloServiceImpl()); + rpcServerUnexport.exportAll(); + + RpcConsumerConfig clientConfig = rpcClient.config(); + HelloService client = clientConfig.serviceProxy(HelloService.class); + + Assert.assertEquals("hello tom!", client.hello("tom")); + + rpcServerUnexport.unexport(service); + + Assert.assertThrows(SofaRpcException.class, () -> { + client.hello("tom"); + }); + + stopServer(rpcServerUnexport); + } + + @Test + public void testUnexportAllService() { + RpcServer rpcServerUnexport = new RpcServer(config(true)); + + RpcProviderConfig serverConfig = rpcServerUnexport.config(); + serverConfig.addService(HelloService.class, new HelloServiceImpl()); + serverConfig.addService("graph", HelloService.class, + new GraphHelloServiceImpl("graph")); + rpcServerUnexport.exportAll(); + + RpcConsumerConfig clientConfig = rpcClient.config(); + HelloService client = clientConfig.serviceProxy(HelloService.class); + HelloService clientG = clientConfig.serviceProxy("graph", + HelloService.class); + + Assert.assertEquals("hello tom!", client.hello("tom")); + Assert.assertEquals("graph: hello tom!", clientG.hello("tom")); + + rpcServerUnexport.unexportAll(); + + Assert.assertThrows(SofaRpcException.class, () -> { + client.hello("tom"); + }); + Assert.assertThrows(SofaRpcException.class, () -> { + clientG.hello("tom"); + }); + + stopServer(rpcServerUnexport); + } + + @Test + public void testUnexportNotExistService() { + Assert.assertThrows(IllegalArgumentException.class, () -> { + rpcServer.unexport("fake"); + }, e -> { + Assert.assertContains("The service 'fake' doesn't exist", + e.getMessage()); + }); + } + + @Test + public void testServerDisabled() { + HugeConfig clientConf = config(false); + RpcServer rpcServerDisabled = new RpcServer(clientConf); + + Assert.assertFalse(rpcServerDisabled.enabled()); + Assert.assertThrows(IllegalArgumentException.class, rpcServerDisabled::config, e -> { + Assert.assertContains("RpcServer is not enabled", e.getMessage()); + }); + + stopServer(rpcServerDisabled); + } + + @Test + public void testClientDisabled() { + HugeConfig serverConf = config(true); + RpcClientProvider rpcClientDisabled = new RpcClientProvider(serverConf); + + Assert.assertFalse(rpcClientDisabled.enabled()); + Assert.assertThrows(IllegalArgumentException.class, rpcClientDisabled::config, e -> { + Assert.assertContains("RpcClient is not enabled", e.getMessage()); + }); + + rpcClientDisabled.destroy(); + } + + @Test + public void testInitRpcConfigs() { + ImmutableMap fixedOptions = ImmutableMap.of( + RpcOptions.PROVIDER_REPEATED_EXPORT_LIMIT, 1); + RpcCommonConfig.initRpcConfigs(fixedOptions); + + RpcCommonConfig.initRpcConfigs(RpcOptions.CONSUMER_RETRIES, 2); + } + + public interface HelloService { + + String hello(String string); + + String echo(String string); + + double sum(long a, double b); + } + + public static class HelloServiceImpl implements HelloService { + + @Override + public String hello(String string) { + E.checkArgument(!string.isEmpty(), "empty hello parameter"); + return "hello " + string + "!"; + } + + @Override + public String echo(String string) { + return string; + } + + @Override + public double sum(long a, double b) { + return a + b; + } + } + + public static class GraphHelloServiceImpl implements HelloService { + + private final String graph; + private double result; + + public GraphHelloServiceImpl(String graph) { + this.graph = graph; + } + + public String graph() { + return this.graph; + } + + public void resetResult() { + this.result = 0.0; + } + + public double result() { + return this.result; + } + + @Override + public String hello(String string) { + E.checkArgument(!string.isEmpty(), "empty hello parameter"); + return this.graph + ": hello " + string + "!"; + } + + @Override + public String echo(String string) { + return this.graph + ": " + string; + } + + @Override + public double sum(long a, double b) { + this.result = a + b; + return this.result; + } + } +} diff --git a/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java new file mode 100644 index 0000000000..a19b5522c8 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java @@ -0,0 +1,30 @@ +/* + * 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.unit; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + VersionTest.class, + ExceptionTest.class, + ServerClientTest.class +}) +public class UnitTestSuite { +} diff --git a/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/VersionTest.java b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/VersionTest.java new file mode 100644 index 0000000000..56d0bc552c --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/VersionTest.java @@ -0,0 +1,36 @@ +/* + * 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.unit; + +import org.junit.Test; + +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.util.VersionUtil; +import org.apache.hugegraph.version.RpcVersion; + +public class VersionTest { + + @Test + public void testGetRpcVersion() { + String pomVersion = VersionUtil.getPomVersion(); + Assert.assertNotNull(pomVersion); + String version = RpcVersion.VERSION.get(); + Assert.assertNotNull(version); + Assert.assertEquals(pomVersion, version); + } +} diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/log4j2.xml b/hugegraph-commons/hugegraph-rpc/src/test/resources/log4j2.xml new file mode 100644 index 0000000000..e84e39584f --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/log4j2.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client-lb.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client-lb.properties new file mode 100644 index 0000000000..3040bf78cd --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client-lb.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +#rpc.server_host=127.0.0.1 +#rpc.server_port=8090 +#rpc.server_timeout=30 +rpc.remote_url=127.0.0.1:8093,127.0.0.1:8094,127.0.0.1:8095 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client.properties new file mode 100644 index 0000000000..332a4fb5a5 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +#rpc.server_host=127.0.0.1 +#rpc.server_port=8090 +#rpc.server_timeout=30 +rpc.remote_url=127.0.0.1:8090 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client345.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client345.properties new file mode 100644 index 0000000000..ef6b36dc27 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client345.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +#rpc.server_host=127.0.0.1 +#rpc.server_port=8090 +#rpc.server_timeout=30 +rpc.remote_url=127.0.0.1:8093,127.0.0.1:8094,127.0.0.1:8095 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client346.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client346.properties new file mode 100644 index 0000000000..6c651bcabb --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client346.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +#rpc.server_host=127.0.0.1 +#rpc.server_port=8090 +#rpc.server_timeout=30 +rpc.remote_url=127.0.0.1:8093,127.0.0.1:8094,127.0.0.1:8096 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client67.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client67.properties new file mode 100644 index 0000000000..7c266da60d --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-client67.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +#rpc.server_host=127.0.0.1 +#rpc.server_port=8090 +#rpc.server_timeout=30 +rpc.remote_url=127.0.0.1:8096,127.0.0.1:8097 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server-adaptive.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server-adaptive.properties new file mode 100644 index 0000000000..043f99cda7 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server-adaptive.properties @@ -0,0 +1,27 @@ +# +# 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. +# + +rpc.server_host=127.0.0.1 +rpc.server_port=8098 +rpc.server_adaptive_port=true +#rpc.server_timeout=30 +#rpc.remote_url=127.0.0.1:8090 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server-random.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server-random.properties new file mode 100644 index 0000000000..6fd695764b --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server-random.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +rpc.server_host=127.0.0.1 +rpc.server_port=0 +#rpc.server_timeout=30 +#rpc.remote_url=127.0.0.1:8090 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server.properties new file mode 100644 index 0000000000..baaf638b4c --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +rpc.server_host=127.0.0.1 +rpc.server_port=8090 +#rpc.server_timeout=30 +#rpc.remote_url=127.0.0.1:8090 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server1-client.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server1-client.properties new file mode 100644 index 0000000000..d40a797f6f --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server1-client.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +rpc.server_host=127.0.0.1 +rpc.server_port=8091 +#rpc.server_timeout=30 +rpc.remote_url=127.0.0.1:8092 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server2-client.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server2-client.properties new file mode 100644 index 0000000000..b368a0a403 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server2-client.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +rpc.server_host=127.0.0.1 +rpc.server_port=8092 +#rpc.server_timeout=30 +rpc.remote_url=127.0.0.1:8091 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server3.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server3.properties new file mode 100644 index 0000000000..56c5719f21 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server3.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +rpc.server_host=127.0.0.1 +rpc.server_port=8093 +#rpc.server_timeout=30 +#rpc.remote_url=127.0.0.1:8090 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server4.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server4.properties new file mode 100644 index 0000000000..1cb7e582d5 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server4.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +rpc.server_host=127.0.0.1 +rpc.server_port=8094 +#rpc.server_timeout=30 +#rpc.remote_url=127.0.0.1:8090 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server5.properties b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server5.properties new file mode 100644 index 0000000000..ec7b647172 --- /dev/null +++ b/hugegraph-commons/hugegraph-rpc/src/test/resources/rpc-server5.properties @@ -0,0 +1,26 @@ +# +# 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. +# + +rpc.server_host=127.0.0.1 +rpc.server_port=8095 +#rpc.server_timeout=30 +#rpc.remote_url=127.0.0.1:8090 +#rpc.client_connect_timeout=20 +#rpc.client_reconnect_period=10 +#rpc.client_read_timeout=40 +#rpc.client_retries=3 +#rpc.client_load_balancer=consistentHash diff --git a/hugegraph-commons/pom.xml b/hugegraph-commons/pom.xml new file mode 100644 index 0000000000..09cd71e5a7 --- /dev/null +++ b/hugegraph-commons/pom.xml @@ -0,0 +1,355 @@ + + + + 4.0.0 + + hugegraph-commons + ${revision} + pom + + ${project.artifactId} + https://github.com/apache/hugegraph-commons + + hugegraph-commons is a common module for HugeGraph-Common and HugeGraph-Rpc with their + peripheral components. + It includes rpc frame, locks, configurations, events, iterators, rest and some numeric or + collection util classes to simplify the development of HugeGraph and its components. + + + + org.apache.hugegraph + hugegraph + ${revision} + ../pom.xml + + + + + The Apache Software License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Apache Hugegraph(Incubating) + dev-subscribe@hugegraph.apache.org + https://hugegraph.apache.org/ + + + + + + Developer List + dev-subscribe@hugegraph.apache.org + dev-unsubscribe@hugegraph.apache.org + dev@hugegraph.incubator.apache.org + + + Commits List + commits-subscribe@hugegraph.apache.org + commits-unsubscribe@hugegraph.apache.org + commits@hugegraph.apache.org + + + Issues List + issues-subscribe@hugegraph.apache.org + issues-unsubscribe@hugegraph.apache.org + issues@hugegraph.apache.org + + + + + Github Issues + https://github.com/apache/hugegraph-commons/issues + + + + https://github.com/apache/hugegraph-commons + scm:git:https://github.com/apache/hugegraph-commons.git + scm:git:https://github.com/apache/hugegraph-commons.git + + + + + 1.5.0 + UTF-8 + ${project.basedir}/.. + 1.8 + 1.8 + 2.18.0 + 1.10 + 2.8.0 + 1.9.4 + 3.2.2 + 3.12.0 + 2.7 + 1.13 + 30.0-jre + 1.0 + 3.0.1 + 3.28.0-GA + 3.0.3 + 3.0.3 + 2.14.0-rc1 + 4.13.1 + 4.1.0 + 4.0.0-RC2 + 3.0.2 + 3.1.2 + 8.45 + true + + + + hugegraph-common + hugegraph-rpc + + + + + + + + maven-compiler-plugin + + ${compiler.source} + ${compiler.target} + + 500 + + + -Xlint:unchecked + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle.plugin.version} + + + com.puppycrawl.tools + checkstyle + ${checkstyle.version} + + + + style/checkstyle.xml + UTF-8 + true + true + false + false + + + + validate + validate + + check + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + true + + false + true + + + + ${project.version} + + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.7 + + + pre-unit-test + + prepare-agent + + + + post-unit-test + test + + report + + + ${project.build.directory} + + + + + + + org.apache.rat + apache-rat-plugin + + + **/*.versionsBackup + **/*.log + **/*.txt + **/*.json + **/*.conf + dist/**/* + docs/**/* + scripts/dev/reviewers + **/*.md + **/.flattened-pom.xml + **/logs/*.log + **/target/* + style/* + ChangeLog + CONFIG.ini + GROUPS + OWNERS + DISCLAIMER + + .github/**/* + + **/*.iml + **/*.iws + **/*.ipr + **/META-INF/MANIFEST.MF + + .repository/** + + true + + + + + org.codehaus.mojo + flatten-maven-plugin + 1.3.0 + + true + resolveCiFriendliesOnly + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.20 + + ${skipCommonsTests} + + + + + + + + apache-release + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + + none + false + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + --pinentry-mode + loopback + + + + + + + + diff --git a/hugegraph-pd/Dockerfile b/hugegraph-pd/Dockerfile index e507900ade..6ab5817f24 100644 --- a/hugegraph-pd/Dockerfile +++ b/hugegraph-pd/Dockerfile @@ -23,7 +23,7 @@ COPY . /pkg WORKDIR /pkg ARG MAVEN_ARGS -RUN mvn package $MAVEN_ARGS -e -B -ntp -DskipTests -Dmaven.javadoc.skip=true && pwd && ls -l && rm \ +RUN mvn package $MAVEN_ARGS -e -B -ntp -Dmaven.test.skip=true -Dmaven.javadoc.skip=true && pwd && ls -l && rm \ ./hugegraph-server/*.tar.gz && rm ./hugegraph-pd/*.tar.gz && rm ./hugegraph-store/*.tar.gz # 2nd stage: runtime env diff --git a/hugegraph-pd/hg-pd-client/pom.xml b/hugegraph-pd/hg-pd-client/pom.xml index f3cb23cf83..2eaab8ac0a 100644 --- a/hugegraph-pd/hg-pd-client/pom.xml +++ b/hugegraph-pd/hg-pd-client/pom.xml @@ -34,7 +34,6 @@ org.projectlombok lombok - 1.18.20 org.apache.logging.log4j diff --git a/hugegraph-pd/hg-pd-common/pom.xml b/hugegraph-pd/hg-pd-common/pom.xml index 4885b1b0bf..79cfbe4112 100644 --- a/hugegraph-pd/hg-pd-common/pom.xml +++ b/hugegraph-pd/hg-pd-common/pom.xml @@ -38,7 +38,6 @@ org.projectlombok lombok - 1.18.24 org.apache.commons diff --git a/hugegraph-pd/hg-pd-common/src/main/java/org/apache/hugegraph/pd/common/GraphCache.java b/hugegraph-pd/hg-pd-common/src/main/java/org/apache/hugegraph/pd/common/GraphCache.java index 07c7c332d9..8a576e1b6b 100644 --- a/hugegraph-pd/hg-pd-common/src/main/java/org/apache/hugegraph/pd/common/GraphCache.java +++ b/hugegraph-pd/hg-pd-common/src/main/java/org/apache/hugegraph/pd/common/GraphCache.java @@ -22,6 +22,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantReadWriteLock; +import com.google.common.collect.Range; + import org.apache.hugegraph.pd.grpc.Metapb.Graph; import org.apache.hugegraph.pd.grpc.Metapb.Partition; @@ -39,7 +41,7 @@ public class GraphCache { private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private Map state = new ConcurrentHashMap<>(); private Map partitions = new ConcurrentHashMap<>(); - private RangeMap range = TreeRangeMap.create(); + private RangeMap range = new SynchronizedRangeMap().rangeMap; public GraphCache(Graph graph) { this.graph = graph; @@ -59,4 +61,56 @@ public Partition addPartition(Integer id, Partition p) { public Partition removePartition(Integer id) { return partitions.remove(id); } + + public class SynchronizedRangeMap, V> { + + private final RangeMap rangeMap = TreeRangeMap.create(); + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + + public void put(Range range, V value) { + lock.writeLock().lock(); + try { + rangeMap.put(range, value); + } finally { + lock.writeLock().unlock(); + } + } + + public V get(K key) { + lock.readLock().lock(); + try { + return rangeMap.get(key); + } finally { + lock.readLock().unlock(); + } + } + + public void remove(Range range) { + lock.writeLock().lock(); + try { + rangeMap.remove(range); + } finally { + lock.writeLock().unlock(); + } + } + + public Map.Entry, V> getEntry(K key) { + lock.readLock().lock(); + try { + return rangeMap.getEntry(key); + } finally { + lock.readLock().unlock(); + } + } + + public void clear() { + lock.writeLock().lock(); + try { + rangeMap.clear(); + } finally { + lock.writeLock().unlock(); + } + } + } + } diff --git a/hugegraph-pd/hg-pd-common/src/main/java/org/apache/hugegraph/pd/common/PartitionCache.java b/hugegraph-pd/hg-pd-common/src/main/java/org/apache/hugegraph/pd/common/PartitionCache.java index 9b98cbbb03..31cc29deed 100644 --- a/hugegraph-pd/hg-pd-common/src/main/java/org/apache/hugegraph/pd/common/PartitionCache.java +++ b/hugegraph-pd/hg-pd-common/src/main/java/org/apache/hugegraph/pd/common/PartitionCache.java @@ -85,7 +85,7 @@ public void waitGraphLock(String graphName) { public void lockGraph(String graphName) { var lock = getOrCreateGraphLock(graphName); - while (lock.compareAndSet(false, true)) { + while (!lock.compareAndSet(false, true)) { Thread.onSpinWait(); } } diff --git a/hugegraph-pd/hg-pd-core/pom.xml b/hugegraph-pd/hg-pd-core/pom.xml index 1f23259d21..e17570d592 100644 --- a/hugegraph-pd/hg-pd-core/pom.xml +++ b/hugegraph-pd/hg-pd-core/pom.xml @@ -72,7 +72,6 @@ org.projectlombok lombok - 1.18.24 org.apache.commons diff --git a/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/start-hugegraph-pd.sh b/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/start-hugegraph-pd.sh index 151465ec6d..b5d5346f34 100644 --- a/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/start-hugegraph-pd.sh +++ b/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/start-hugegraph-pd.sh @@ -101,14 +101,20 @@ fi # Using G1GC as the default garbage collector (Recommended for large memory machines) case "$GC_OPTION" in - g1) + "") echo "Using G1GC as the default garbage collector" - JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+UseG1GC -XX:+ParallelRefProcEnabled \ + JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+ParallelRefProcEnabled \ -XX:InitiatingHeapOccupancyPercent=50 -XX:G1RSetUpdatingPauseTimePercent=5" ;; - "") ;; + zgc|ZGC) + echo "Using ZGC as the default garbage collector (Only support Java 11+)" + JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+UseZGC -XX:+UnlockExperimentalVMOptions \ + -XX:ConcGCThreads=2 -XX:ParallelGCThreads=6 \ + -XX:ZCollectionInterval=120 -XX:ZAllocationSpikeTolerance=5 \ + -XX:+UnlockDiagnosticVMOptions -XX:-ZProactive" + ;; *) - echo "Unrecognized gc option: '$GC_OPTION', only support 'g1' now" >> ${OUTPUT} + echo "Unrecognized gc option: '$GC_OPTION', default use g1, options only support 'ZGC' now" >> ${OUTPUT} exit 1 esac diff --git a/hugegraph-pd/hg-pd-service/pom.xml b/hugegraph-pd/hg-pd-service/pom.xml index 14fed89ee0..37c90fe869 100644 --- a/hugegraph-pd/hg-pd-service/pom.xml +++ b/hugegraph-pd/hg-pd-service/pom.xml @@ -114,7 +114,6 @@ org.projectlombok lombok - 1.18.24 diff --git a/hugegraph-pd/hg-pd-test/pom.xml b/hugegraph-pd/hg-pd-test/pom.xml index 440346611c..a2a7c67873 100644 --- a/hugegraph-pd/hg-pd-test/pom.xml +++ b/hugegraph-pd/hg-pd-test/pom.xml @@ -75,7 +75,6 @@ org.projectlombok lombok - 1.18.24 org.springframework diff --git a/hugegraph-server/Dockerfile b/hugegraph-server/Dockerfile index 0e39704fd6..6e68149f0a 100644 --- a/hugegraph-server/Dockerfile +++ b/hugegraph-server/Dockerfile @@ -23,14 +23,14 @@ COPY . /pkg WORKDIR /pkg ARG MAVEN_ARGS -RUN mvn package $MAVEN_ARGS -e -B -ntp -DskipTests -Dmaven.javadoc.skip=true && pwd && ls -l && rm \ +RUN mvn package $MAVEN_ARGS -e -B -ntp -Dmaven.test.skip=true -Dmaven.javadoc.skip=true && pwd && ls -l && rm \ ./hugegraph-server/*.tar.gz && rm ./hugegraph-pd/*.tar.gz && rm ./hugegraph-store/*.tar.gz # 2nd stage: runtime env # Note: ZGC (The Z Garbage Collector) is only supported on ARM-Mac with java > 13 FROM openjdk:11-slim -COPY --from=build /pkg/hugegraph-server/apache-hugegraph-incubating-server-*/ /hugegraph-server/ +COPY --from=build /pkg/hugegraph-server/apache-hugegraph-server-incubating-*/ /hugegraph-server/ LABEL maintainer="HugeGraph Docker Maintainers " # TODO: use g1gc or zgc as default diff --git a/hugegraph-server/Dockerfile-hstore b/hugegraph-server/Dockerfile-hstore new file mode 100644 index 0000000000..47f758b0d5 --- /dev/null +++ b/hugegraph-server/Dockerfile-hstore @@ -0,0 +1,73 @@ +# +# 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. +# + +# Dockerfile for HugeGraph Server +# 1st stage: build source code +FROM maven:3.9.0-eclipse-temurin-11 AS build + +COPY . /pkg +WORKDIR /pkg +ARG MAVEN_ARGS + +RUN mvn package $MAVEN_ARGS -e -B -ntp -DskipTests -Dmaven.javadoc.skip=true && pwd && ls -l && rm \ + ./hugegraph-server/*.tar.gz && rm ./hugegraph-pd/*.tar.gz && rm ./hugegraph-store/*.tar.gz + +# 2nd stage: runtime env +# Note: ZGC (The Z Garbage Collector) is only supported on ARM-Mac with java > 13 +FROM openjdk:11-slim + +COPY --from=build /pkg/hugegraph-server/apache-hugegraph-server-incubating-*/ /hugegraph-server/ +# remove hugegraph.properties and rename hstore.properties.template for default hstore backend +RUN cd /hugegraph-server/conf/graphs \ + && rm hugegraph.properties && mv hstore.properties.template hugegraph.properties + +LABEL maintainer="HugeGraph Docker Maintainers " + +# TODO: use g1gc or zgc as default +ENV JAVA_OPTS="-XX:+UnlockExperimentalVMOptions -XX:+UseContainerSupport -XX:MaxRAMPercentage=50 -XshowSettings:vm" \ + HUGEGRAPH_HOME="hugegraph-server" + +#COPY . /hugegraph/hugegraph-server +WORKDIR /hugegraph-server/ + +# 1. Install environment and init HugeGraph Sever +RUN set -x \ + && apt-get -q update \ + && apt-get -q install -y --no-install-recommends --no-install-suggests \ + dumb-init \ + procps \ + curl \ + lsof \ + vim \ + cron \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && service cron start \ + && pwd && cd /hugegraph-server/ \ + && sed -i "s/^restserver.url.*$/restserver.url=http:\/\/0.0.0.0:8080/g" ./conf/rest-server.properties + +# 2. Init docker script +COPY hugegraph-server/hugegraph-dist/docker/scripts/remote-connect.groovy ./scripts +COPY hugegraph-server/hugegraph-dist/docker/scripts/detect-storage.groovy ./scripts +COPY hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh . +RUN chmod 755 ./docker-entrypoint.sh + +EXPOSE 8080 +VOLUME /hugegraph-server + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["./docker-entrypoint.sh"] diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java index d429db4d9b..ae53686467 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java @@ -26,7 +26,6 @@ import java.io.IOException; import java.net.URI; -import org.apache.hugegraph.auth.HugeAuthenticator; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.config.ServerOptions; import org.apache.hugegraph.core.GraphManager; @@ -124,7 +123,7 @@ public void filter(ContainerRequestContext requestContext, GraphManager manager = managerProvider.get(); // TODO: transfer Authorizer if we need after. if (manager.requireAuthentication()) { - manager.unauthorize(requestContext.getSecurityContext()); + manager.unauthorized(requestContext.getSecurityContext()); } } diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/GraphSpaceFilter.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/GraphSpaceFilter.java new file mode 100644 index 0000000000..97e0cec935 --- /dev/null +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/GraphSpaceFilter.java @@ -0,0 +1,126 @@ +/* + * 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.api.filter; + +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.stream.Collectors; + +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.config.ServerOptions; +import org.apache.hugegraph.util.Log; +import org.slf4j.Logger; + +import jakarta.inject.Singleton; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerRequestFilter; +import jakarta.ws.rs.container.PreMatching; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.UriBuilder; +import jakarta.ws.rs.ext.Provider; + +/** + * TODO: Change the adaptor logic to keep compatibility with the non-"GraphSpace" version after we + * support "GraphSpace" + */ +@Provider +@Singleton +@PreMatching +public class GraphSpaceFilter implements ContainerRequestFilter { + + private static final Logger LOG = Log.logger(GraphSpaceFilter.class); + + private static final String GRAPHSPACES_PATH = "graphspaces/"; + + @Context + private jakarta.inject.Provider configProvider; + + /** + * Filters incoming HTTP requests to modify the request URI if it matches certain criteria. + *

      + * This filter checks if the request URI starts with the {@link #GRAPHSPACES_PATH} path + * segment. If it does, + * the filter removes the {@link #GRAPHSPACES_PATH} segment along with the following segment + * and then reconstructs + * the remaining URI. The modified URI is set back into the request context. This is useful for + * supporting legacy paths or adapting to new API structures. + *

      + * + *

      Example:

      + *
      +     * URI baseUri = URI.create("http://localhost:8080/");
      +     * URI requestUri = URI.create("http://localhost:8080/graphspaces/DEFAULT/graphs");
      +     *
      +     * // Before filter:
      +     * context.getUriInfo().getRequestUri();  // returns http://localhost:8080/graphspaces/DEFAULT/graphs
      +     *
      +     * // After filter:
      +     * context.getUriInfo().getRequestUri();  // returns http://localhost:8080/graphs
      +     * 
      + * + * @param context The {@link ContainerRequestContext} which provides access to the request + * details. + * @throws IOException If an input or output exception occurs. + */ + @Override + public void filter(ContainerRequestContext context) throws IOException { + HugeConfig config = configProvider.get(); + if (!config.get(ServerOptions.REST_SERVER_ENABLE_GRAPHSPACES_FILTER)) { + return; + } + + // Step 1: Get relativePath + URI baseUri = context.getUriInfo().getBaseUri(); + URI requestUri = context.getUriInfo().getRequestUri(); + URI relativePath = baseUri.relativize(requestUri); + + String relativePathStr = relativePath.getPath(); + // TODO: remember remove the logic after we support "GraphSpace" + if (!relativePathStr.startsWith(GRAPHSPACES_PATH)) { + return; + } + + // Step 2: Extract the next substring after {@link #GRAPHSPACES_PATH} + String[] parts = relativePathStr.split("/"); + if (parts.length <= 1) { + return; + } + + String ignoredPart = Arrays.stream(parts) + .limit(2) // Ignore the first two segments + .collect(Collectors.joining("/")); + + // Reconstruct the remaining path + String newPath = Arrays.stream(parts) + .skip(2) // Skip the first two segments + .collect(Collectors.joining("/")); + + // Step 3: Modify RequestUri and log the ignored part + URI newUri = UriBuilder.fromUri(baseUri) + .path(newPath) + .replaceQuery(requestUri.getRawQuery()) + .build(); + context.setRequestUri(newUri); + + // Log the ignored part + if (LOG.isDebugEnabled()) { + LOG.debug("Ignored graphspaces segment: {}", ignoredPart); + } + } +} diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java index 25e8cacf00..6a289368e4 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/graph/EdgeAPI.java @@ -426,7 +426,15 @@ public static Direction parseDirection(String direction) { private Id getEdgeId(HugeGraph g, JsonEdge newEdge) { String sortKeys = ""; - Id labelId = g.edgeLabel(newEdge.label).id(); + EdgeLabel edgeLabel = g.edgeLabel(newEdge.label); + E.checkArgument(!edgeLabel.edgeLabelType().parent(), + "The label of the created/updated edge is not allowed" + + " to be the parent type"); + Id labelId = edgeLabel.id(); + Id subLabelId = edgeLabel.id(); + if (edgeLabel.edgeLabelType().sub()) { + labelId = edgeLabel.fatherId(); + } List sortKeyIds = g.edgeLabel(labelId).sortKeys(); if (!sortKeyIds.isEmpty()) { List sortKeyValues = new ArrayList<>(sortKeyIds.size()); @@ -442,7 +450,7 @@ private Id getEdgeId(HugeGraph g, JsonEdge newEdge) { sortKeys = ConditionQuery.concatValues(sortKeyValues); } EdgeId edgeId = new EdgeId(HugeVertex.getIdValue(newEdge.source), - Directions.OUT, labelId, sortKeys, + Directions.OUT, labelId, subLabelId, sortKeys, HugeVertex.getIdValue(newEdge.target)); if (newEdge.id != null) { E.checkArgument(edgeId.asString().equals(newEdge.id), diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/EdgeLabelAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/EdgeLabelAPI.java index 97bad8c778..7e80afb61a 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/EdgeLabelAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/schema/EdgeLabelAPI.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.commons.collections.CollectionUtils; import org.apache.hugegraph.HugeGraph; @@ -32,6 +33,7 @@ import org.apache.hugegraph.define.Checkable; import org.apache.hugegraph.schema.EdgeLabel; import org.apache.hugegraph.schema.Userdata; +import org.apache.hugegraph.type.define.EdgeLabelType; import org.apache.hugegraph.type.define.Frequency; import org.apache.hugegraph.type.define.GraphMode; import org.apache.hugegraph.util.E; @@ -183,10 +185,16 @@ private static class JsonEdgeLabel implements Checkable { public long id; @JsonProperty("name") public String name; + @JsonProperty("edgelabel_type") + public EdgeLabelType edgeLabelType; + @JsonProperty("parent_label") + public String fatherLabel; @JsonProperty("source_label") public String sourceLabel; @JsonProperty("target_label") public String targetLabel; + @JsonProperty("links") + public Set> links; @JsonProperty("frequency") public Frequency frequency; @JsonProperty("properties") @@ -223,12 +231,33 @@ private EdgeLabel.Builder convert2Builder(HugeGraph g) { g, g.mode()); builder.id(this.id); } + if (this.edgeLabelType == null) { + this.edgeLabelType = EdgeLabelType.NORMAL; + } else if (this.edgeLabelType.parent()) { + builder.asBase(); + } else if (this.edgeLabelType.sub()) { + builder.withBase(this.fatherLabel); + } else { + E.checkArgument(this.edgeLabelType.normal(), + "Please enter a valid edge_label_type value " + + "in [NORMAL, PARENT, SUB]"); + } if (this.sourceLabel != null) { builder.sourceLabel(this.sourceLabel); } if (this.targetLabel != null) { builder.targetLabel(this.targetLabel); } + if (this.links != null && !this.links.isEmpty()) { + for (Map map : this.links) { + E.checkArgument(map.size() == 1, + "The map size must be 1, due to it is a " + + "pair"); + Map.Entry entry = + map.entrySet().iterator().next(); + builder.link(entry.getKey(), entry.getValue()); + } + } if (this.frequency != null) { builder.frequency(this.frequency); } diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java index 63da169c99..5c5aa86e3d 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java @@ -21,6 +21,7 @@ import static org.apache.hugegraph.config.OptionChecker.disallowEmpty; import static org.apache.hugegraph.config.OptionChecker.nonNegativeInt; import static org.apache.hugegraph.config.OptionChecker.positiveInt; +import static org.apache.hugegraph.config.OptionChecker.rangeDouble; import static org.apache.hugegraph.config.OptionChecker.rangeInt; public class ServerOptions extends OptionHolder { @@ -47,6 +48,14 @@ public static synchronized ServerOptions instance() { "http://127.0.0.1:8080" ); + public static final ConfigOption REST_SERVER_ENABLE_GRAPHSPACES_FILTER = + new ConfigOption<>( + "restserver.enable_graphspaces_filter", + "Whether to enable graphspaces url filter.", + disallowEmpty(), + false + ); + public static final ConfigOption SERVER_ID = new ConfigOption<>( "server.id", @@ -313,4 +322,22 @@ public static synchronized ServerOptions instance() { nonNegativeInt(), 1000L ); + + public static final ConfigOption JVM_MEMORY_MONITOR_THRESHOLD = + new ConfigOption<>( + "memory_monitor.threshold", + "Threshold for JVM memory usage monitoring, 1 means disabling the memory " + + "monitoring task.", + rangeDouble(0.0, 1.0), + 0.85 + ); + + public static final ConfigOption JVM_MEMORY_MONITOR_DETECT_PERIOD = + new ConfigOption<>( + "memory_monitor.period", + "The period in ms of JVM memory usage monitoring, in each period we will " + + "detect the jvm memory usage and take corresponding actions.", + nonNegativeInt(), + 2000 + ); } diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/core/GraphManager.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/core/GraphManager.java index 37939c2019..9a9d957e8b 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/core/GraphManager.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/core/GraphManager.java @@ -265,7 +265,7 @@ public HugeAuthenticator.User authenticate(Map credentials) return this.authenticator().authenticate(credentials); } - public void unauthorize(SecurityContext context) { + public void unauthorized(SecurityContext context) { this.authenticator().unauthorize(context); } @@ -401,17 +401,17 @@ private void loadGraph(String name, String graphConfPath) { } private void transferRoleWorkerConfig(HugeConfig config) { - config.addProperty(RoleElectionOptions.NODE_EXTERNAL_URL.name(), + config.setProperty(RoleElectionOptions.NODE_EXTERNAL_URL.name(), this.conf.get(ServerOptions.REST_SERVER_URL)); - config.addProperty(RoleElectionOptions.BASE_TIMEOUT_MILLISECOND.name(), + config.setProperty(RoleElectionOptions.BASE_TIMEOUT_MILLISECOND.name(), this.conf.get(RoleElectionOptions.BASE_TIMEOUT_MILLISECOND)); - config.addProperty(RoleElectionOptions.EXCEEDS_FAIL_COUNT.name(), + config.setProperty(RoleElectionOptions.EXCEEDS_FAIL_COUNT.name(), this.conf.get(RoleElectionOptions.EXCEEDS_FAIL_COUNT)); - config.addProperty(RoleElectionOptions.RANDOM_TIMEOUT_MILLISECOND.name(), + config.setProperty(RoleElectionOptions.RANDOM_TIMEOUT_MILLISECOND.name(), this.conf.get(RoleElectionOptions.RANDOM_TIMEOUT_MILLISECOND)); - config.addProperty(RoleElectionOptions.HEARTBEAT_INTERVAL_SECOND.name(), + config.setProperty(RoleElectionOptions.HEARTBEAT_INTERVAL_SECOND.name(), this.conf.get(RoleElectionOptions.HEARTBEAT_INTERVAL_SECOND)); - config.addProperty(RoleElectionOptions.MASTER_DEAD_TIMES.name(), + config.setProperty(RoleElectionOptions.MASTER_DEAD_TIMES.name(), this.conf.get(RoleElectionOptions.MASTER_DEAD_TIMES)); } @@ -515,7 +515,7 @@ private boolean supportRoleElection() { private void addMetrics(HugeConfig config) { final MetricManager metric = MetricManager.INSTANCE; - // Force to add server reporter + // Force to add a server reporter ServerReporter reporter = ServerReporter.instance(metric.getRegistry()); reporter.start(60L, TimeUnit.SECONDS); @@ -610,7 +610,7 @@ private void dropGraph(HugeGraph graph) { /* * Will fill graph instance into HugeFactory.graphs after - * GraphFactory.open() succeed, remove it when graph drop + * GraphFactory.open() succeed, remove it when the graph drops */ HugeFactory.remove(graph); } diff --git a/hugegraph-server/hugegraph-cassandra/src/main/java/org/apache/hugegraph/backend/store/cassandra/CassandraFeatures.java b/hugegraph-server/hugegraph-cassandra/src/main/java/org/apache/hugegraph/backend/store/cassandra/CassandraFeatures.java index 3ca43050d3..0993fde1be 100644 --- a/hugegraph-server/hugegraph-cassandra/src/main/java/org/apache/hugegraph/backend/store/cassandra/CassandraFeatures.java +++ b/hugegraph-server/hugegraph-cassandra/src/main/java/org/apache/hugegraph/backend/store/cassandra/CassandraFeatures.java @@ -21,6 +21,11 @@ public class CassandraFeatures implements BackendFeatures { + @Override + public boolean supportsFatherAndSubEdgeLabel() { + return false; + } + @Override public boolean supportsScanToken() { return true; diff --git a/hugegraph-server/hugegraph-cassandra/src/main/java/org/apache/hugegraph/backend/store/cassandra/CassandraTables.java b/hugegraph-server/hugegraph-cassandra/src/main/java/org/apache/hugegraph/backend/store/cassandra/CassandraTables.java index 40b7e5a19d..ece8f2ae8e 100644 --- a/hugegraph-server/hugegraph-cassandra/src/main/java/org/apache/hugegraph/backend/store/cassandra/CassandraTables.java +++ b/hugegraph-server/hugegraph-cassandra/src/main/java/org/apache/hugegraph/backend/store/cassandra/CassandraTables.java @@ -21,6 +21,8 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import org.apache.hugegraph.backend.BackendException; import org.apache.hugegraph.backend.id.EdgeId; @@ -51,6 +53,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import org.apache.hugegraph.util.HashUtil; + public class CassandraTables { public static final String LABEL_INDEX = "label_index"; @@ -400,7 +404,9 @@ protected List pkColumnName() { @Override protected List idColumnName() { - return Arrays.asList(EdgeId.KEYS); + return Arrays.stream(EdgeId.KEYS) + .filter(key -> !Objects.equals(key, HugeKeys.SUB_LABEL)) + .collect(Collectors.toList()); } @Override diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java index ab460d495f..13d654d174 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java @@ -19,9 +19,12 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; +import org.apache.commons.lang3.tuple.Pair; import org.apache.hugegraph.auth.AuthManager; import org.apache.hugegraph.backend.id.Id; import org.apache.hugegraph.backend.query.Query; @@ -300,11 +303,25 @@ default Id[] mapElName2Id(String[] edgeLabels) { Id[] ids = new Id[edgeLabels.length]; for (int i = 0; i < edgeLabels.length; i++) { EdgeLabel edgeLabel = this.edgeLabel(edgeLabels[i]); - ids[i] = edgeLabel.id(); + if (edgeLabel.hasFather()) { + ids[i] = edgeLabel.fatherId(); + } else { + ids[i] = edgeLabel.id(); + } } return ids; } + default Set> mapPairId2Name( + Set> pairs) { + Set> results = new HashSet<>(pairs.size()); + for (Pair pair : pairs) { + results.add(Pair.of(this.vertexLabel(pair.getLeft()).name(), + this.vertexLabel(pair.getRight()).name())); + } + return results; + } + default Id[] mapVlName2Id(String[] vertexLabels) { Id[] ids = new Id[vertexLabels.length]; for (int i = 0; i < vertexLabels.length; i++) { @@ -314,6 +331,14 @@ default Id[] mapVlName2Id(String[] vertexLabels) { return ids; } + default EdgeLabel[] mapElName2El(String[] edgeLabels) { + EdgeLabel[] els = new EdgeLabel[edgeLabels.length]; + for (int i = 0; i < edgeLabels.length; i++) { + els[i] = this.edgeLabel(edgeLabels[i]); + } + return els; + } + static void registerTraversalStrategies(Class clazz) { TraversalStrategies strategies = TraversalStrategies.GlobalCache .getStrategies(Graph.class) diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java index 4e9263a488..6480d7f288 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java @@ -316,8 +316,7 @@ private void initRoleStateMachine(Id serverId) { conf.get( RoleElectionOptions.BASE_TIMEOUT_MILLISECOND)); ClusterRoleStore roleStore = new StandardClusterRoleStore(this.params); - this.roleElectionStateMachine = new StandardRoleElectionStateMachine(roleConfig, - roleStore); + this.roleElectionStateMachine = new StandardRoleElectionStateMachine(roleConfig, roleStore); } @Override @@ -1007,7 +1006,7 @@ public void create(String configPath, GlobalMasterInfo nodeInfo) { this.initBackend(); this.serverStarted(nodeInfo); - // Write config to disk file + // Write config to the disk file String confPath = ConfigUtil.writeToFile(configPath, this.name(), this.configuration()); this.configuration.file(confPath); @@ -1349,7 +1348,7 @@ public String schedulerType() { private class TinkerPopTransaction extends AbstractThreadLocalTransaction { - // Times opened from upper layer + // Times opened from the upper layer private final AtomicInteger refs; // Flag opened of each thread private final ThreadLocal opened; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedBackendStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedBackendStore.java index a1c632d9f5..e266c0623f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedBackendStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedBackendStore.java @@ -18,8 +18,13 @@ package org.apache.hugegraph.backend.cache; import java.util.Iterator; +import java.util.List; +import java.util.function.Function; +import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.backend.query.ConditionQueryFlatten; import org.apache.hugegraph.backend.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.backend.store.BackendFeatures; @@ -28,6 +33,8 @@ import org.apache.hugegraph.backend.store.BackendStoreProvider; import org.apache.hugegraph.backend.store.SystemSchemaStore; import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.iterator.ExtendableIterator; +import org.apache.hugegraph.iterator.MapperIterator; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.util.StringEncoding; @@ -177,6 +184,29 @@ public Iterator query(Query query) { } } + @Override + public Iterator> query(Iterator queries, + Function queryWriter, + HugeGraph hugeGraph) { + return new MapperIterator<>(queries, query -> { + assert query instanceof ConditionQuery; + List flattenQueryList = + ConditionQueryFlatten.flatten((ConditionQuery) query); + + if (flattenQueryList.size() > 1) { + ExtendableIterator itExtend + = new ExtendableIterator<>(); + flattenQueryList.forEach(cq -> { + Query cQuery = queryWriter.apply(cq); + itExtend.extend(this.query(cQuery)); + }); + return itExtend; + } else { + return this.query(queryWriter.apply(query)); + } + }); + } + @Override public Number queryNumber(Query query) { return this.store.queryNumber(query); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/OffheapCache.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/OffheapCache.java index d641c8276f..7ed4efcd66 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/OffheapCache.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/OffheapCache.java @@ -55,14 +55,18 @@ public class OffheapCache extends AbstractCache { private final AbstractSerializer serializer; public OffheapCache(HugeGraph graph, long capacity, long avgEntryBytes) { - // NOTE: capacity unit is bytes, the super capacity expect elements size + this(graph, capacity, avgEntryBytes, Runtime.getRuntime().availableProcessors() * 2); + } + + public OffheapCache(HugeGraph graph, long capacity, long avgEntryBytes, int segments) { + // NOTE: capacity unit is bytes, the super capacity expects elements' size super(capacity); - long capacityInBytes = capacity * (avgEntryBytes + 64L); + long capacityInBytes = Math.max(capacity, segments) * (avgEntryBytes + 64L); if (capacityInBytes <= 0L) { capacityInBytes = 1L; } this.graph = graph; - this.cache = this.builder().capacity(capacityInBytes).build(); + this.cache = this.builder().capacity(capacityInBytes).segmentCount(segments).build(); this.serializer = new BinarySerializer(); } @@ -162,19 +166,18 @@ private class IdSerializer implements CacheSerializer { @Override public Id deserialize(ByteBuffer input) { - return BytesBuffer.wrap(input).readId(true); + return BytesBuffer.wrap(input).readId(); } @Override public void serialize(Id id, ByteBuffer output) { - BytesBuffer.wrap(output).writeId(id, true); + BytesBuffer.wrap(output).writeId(id); } @Override public int serializedSize(Id id) { // NOTE: return size must be == actual bytes to write - return BytesBuffer.allocate(id.length() + 2) - .writeId(id, true).position(); + return BytesBuffer.allocate(id.length() + 2).writeId(id).position(); } } @@ -229,7 +232,6 @@ public ByteBuffer asBuffer() { } BytesBuffer buffer = BytesBuffer.allocate(64 * listSize); - // May fail to serialize and throw exception here this.serialize(this.value, buffer); @@ -276,8 +278,7 @@ private Object deserialize(BytesBuffer buffer) { } } - private void serializeList(BytesBuffer buffer, - Collection list) { + private void serializeList(BytesBuffer buffer, Collection list) { // Write list buffer.writeVInt(list.size()); for (Object i : list) { @@ -295,8 +296,7 @@ private List deserializeList(BytesBuffer buffer) { return list; } - private void serializeElement(BytesBuffer buffer, - ValueType type, Object value) { + private void serializeElement(BytesBuffer buffer, ValueType type, Object value) { E.checkNotNull(value, "serialize value"); BackendEntry entry; if (type == ValueType.VERTEX) { @@ -332,14 +332,12 @@ private Object deserializeElement(ValueType type, BytesBuffer buffer) { } private HugeException unsupported(ValueType type) { - throw new HugeException( - "Unsupported deserialize type: %s", type); + throw new HugeException("Unsupported deserialize type: %s", type); } private HugeException unsupported(Object value) { - throw new HugeException( - "Unsupported type of serialize value: '%s'(%s)", - value, value.getClass()); + throw new HugeException("Unsupported type of serialize value: '%s'(%s)", + value, value.getClass()); } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/EdgeId.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/EdgeId.java index a9053e5135..fe030a153f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/EdgeId.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/EdgeId.java @@ -28,8 +28,13 @@ /** * Class used to format and parse id of edge, the edge id consists of: - * { source-vertex-id + edge-label + edge-name + target-vertex-id } - * NOTE: if we use `entry.type()` which is IN or OUT as a part of id, + * EdgeId = { source-vertex-id > direction > parentEdgeLabelId > subEdgeLabelId + * > sortKeys > target-vertex-id } + * NOTE: + *

      1. for edges with edgeLabelType = NORMAL: edgeLabelId = parentEdgeLabelId = subEdgeLabelId; + * for edges with edgeLabelType = PARENT: edgeLabelId = subEdgeLabelId, parentEdgeLabelId = + * edgeLabelId.fatherId + *

      2.if we use `entry.type()` which is IN or OUT as a part of id, * an edge's id will be different due to different directions (belongs * to 2 owner vertex) */ @@ -39,6 +44,7 @@ public class EdgeId implements Id { HugeKeys.OWNER_VERTEX, HugeKeys.DIRECTION, HugeKeys.LABEL, + HugeKeys.SUB_LABEL, HugeKeys.SORT_VALUES, HugeKeys.OTHER_VERTEX }; @@ -46,6 +52,7 @@ public class EdgeId implements Id { private final Id ownerVertexId; private final Directions direction; private final Id edgeLabelId; + private final Id subLabelId; private final String sortValues; private final Id otherVertexId; @@ -53,22 +60,23 @@ public class EdgeId implements Id { private String cache; public EdgeId(HugeVertex ownerVertex, Directions direction, - Id edgeLabelId, String sortValues, HugeVertex otherVertex) { - this(ownerVertex.id(), direction, edgeLabelId, + Id edgeLabelId, Id subLabelId, String sortValues, HugeVertex otherVertex) { + this(ownerVertex.id(), direction, edgeLabelId, subLabelId, sortValues, otherVertex.id()); } - public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, + public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, Id subLabelId, String sortValues, Id otherVertexId) { - this(ownerVertexId, direction, edgeLabelId, + this(ownerVertexId, direction, edgeLabelId, subLabelId, sortValues, otherVertexId, false); } - public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, + public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, Id subLabelId, String sortValues, Id otherVertexId, boolean directed) { this.ownerVertexId = ownerVertexId; this.direction = direction; this.edgeLabelId = edgeLabelId; + this.subLabelId = subLabelId; this.sortValues = sortValues; this.otherVertexId = otherVertexId; this.directed = directed; @@ -78,12 +86,12 @@ public EdgeId(Id ownerVertexId, Directions direction, Id edgeLabelId, @Watched public EdgeId switchDirection() { Directions direction = this.direction.opposite(); - return new EdgeId(this.otherVertexId, direction, this.edgeLabelId, + return new EdgeId(this.otherVertexId, direction, this.edgeLabelId, this.subLabelId, this.sortValues, this.ownerVertexId, this.directed); } public EdgeId directed(boolean directed) { - return new EdgeId(this.ownerVertexId, this.direction, this.edgeLabelId, + return new EdgeId(this.ownerVertexId, this.direction, this.edgeLabelId, this.subLabelId, this.sortValues, this.otherVertexId, directed); } @@ -107,6 +115,10 @@ public Id edgeLabelId() { return this.edgeLabelId; } + public Id subLabelId() { + return this.subLabelId; + } + public Directions direction() { return this.direction; } @@ -138,12 +150,14 @@ public String asString() { IdUtil.writeString(this.ownerVertexId), this.direction.type().string(), IdUtil.writeLong(this.edgeLabelId), + IdUtil.writeLong(this.subLabelId), this.sortValues, IdUtil.writeString(this.otherVertexId)); } else { this.cache = SplicingIdGenerator.concat( IdUtil.writeString(this.sourceVertexId()), IdUtil.writeLong(this.edgeLabelId), + IdUtil.writeLong(this.subLabelId), this.sortValues, IdUtil.writeString(this.targetVertexId())); } @@ -181,11 +195,13 @@ public int hashCode() { return this.ownerVertexId.hashCode() ^ this.direction.hashCode() ^ this.edgeLabelId.hashCode() ^ + this.subLabelId.hashCode() ^ this.sortValues.hashCode() ^ this.otherVertexId.hashCode(); } else { return this.sourceVertexId().hashCode() ^ this.edgeLabelId.hashCode() ^ + this.subLabelId.hashCode() ^ this.sortValues.hashCode() ^ this.targetVertexId().hashCode(); } @@ -201,11 +217,13 @@ public boolean equals(Object object) { return this.ownerVertexId.equals(other.ownerVertexId) && this.direction == other.direction && this.edgeLabelId.equals(other.edgeLabelId) && + this.subLabelId.equals(other.subLabelId) && this.sortValues.equals(other.sortValues) && this.otherVertexId.equals(other.otherVertexId); } else { return this.sourceVertexId().equals(other.sourceVertexId()) && this.edgeLabelId.equals(other.edgeLabelId) && + this.subLabelId.equals(other.subLabelId) && this.sortValues.equals(other.sortValues) && this.targetVertexId().equals(other.targetVertexId()); } @@ -235,31 +253,33 @@ public static EdgeId parse(String id) throws NotFoundException { public static EdgeId parse(String id, boolean returnNullIfError) throws NotFoundException { String[] idParts = SplicingIdGenerator.split(id); - if (!(idParts.length == 4 || idParts.length == 5)) { + if (!(idParts.length == 5 || idParts.length == 6)) { if (returnNullIfError) { return null; } - throw new NotFoundException("Edge id must be formatted as 4~5 " + + throw new NotFoundException("Edge id must be formatted as 5~6 " + "parts, but got %s parts: '%s'", idParts.length, id); } try { - if (idParts.length == 4) { + if (idParts.length == 5) { Id ownerVertexId = IdUtil.readString(idParts[0]); Id edgeLabelId = IdUtil.readLong(idParts[1]); - String sortValues = idParts[2]; - Id otherVertexId = IdUtil.readString(idParts[3]); - return new EdgeId(ownerVertexId, Directions.OUT, edgeLabelId, + Id subLabelId = IdUtil.readLong(idParts[2]); + String sortValues = idParts[3]; + Id otherVertexId = IdUtil.readString(idParts[4]); + return new EdgeId(ownerVertexId, Directions.OUT, edgeLabelId, subLabelId, sortValues, otherVertexId); } else { - assert idParts.length == 5; + assert idParts.length == 6; Id ownerVertexId = IdUtil.readString(idParts[0]); HugeType direction = HugeType.fromString(idParts[1]); Id edgeLabelId = IdUtil.readLong(idParts[2]); - String sortValues = idParts[3]; - Id otherVertexId = IdUtil.readString(idParts[4]); + Id subLabelId = IdUtil.readLong(idParts[3]); + String sortValues = idParts[4]; + Id otherVertexId = IdUtil.readString(idParts[5]); return new EdgeId(ownerVertexId, Directions.convert(direction), - edgeLabelId, sortValues, otherVertexId); + edgeLabelId, subLabelId, sortValues, otherVertexId); } } catch (Throwable e) { if (returnNullIfError) { @@ -272,12 +292,13 @@ public static EdgeId parse(String id, boolean returnNullIfError) public static Id parseStoredString(String id) { String[] idParts = split(id); - E.checkArgument(idParts.length == 4, "Invalid id format: %s", id); + E.checkArgument(idParts.length == 5, "Invalid id format: %s", id); Id ownerVertexId = IdUtil.readStoredString(idParts[0]); Id edgeLabelId = IdGenerator.ofStoredString(idParts[1], IdType.LONG); - String sortValues = idParts[2]; - Id otherVertexId = IdUtil.readStoredString(idParts[3]); - return new EdgeId(ownerVertexId, Directions.OUT, edgeLabelId, + Id subLabelId = IdGenerator.ofStoredString(idParts[2], IdType.LONG); + String sortValues = idParts[3]; + Id otherVertexId = IdUtil.readStoredString(idParts[4]); + return new EdgeId(ownerVertexId, Directions.OUT, edgeLabelId, subLabelId, sortValues, otherVertexId); } @@ -286,6 +307,7 @@ public static String asStoredString(Id id) { return SplicingIdGenerator.concat( IdUtil.writeStoredString(eid.sourceVertexId()), IdGenerator.asStoredString(eid.edgeLabelId()), + IdGenerator.asStoredString(eid.subLabelId()), eid.sortValues(), IdUtil.writeStoredString(eid.targetVertexId())); } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/Id.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/Id.java index b0e5613495..077aa43dbb 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/Id.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/Id.java @@ -67,8 +67,7 @@ public char prefix() { } public static IdType valueOfPrefix(String id) { - E.checkArgument(id != null && !id.isEmpty(), - "Invalid id '%s'", id); + E.checkArgument(id != null && !id.isEmpty(), "Invalid id '%s'", id); switch (id.charAt(0)) { case 'L': return IdType.LONG; diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/EdgesQueryIterator.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/EdgesQueryIterator.java index a3edd28c42..d8bce082c6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/EdgesQueryIterator.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/EdgesQueryIterator.java @@ -52,7 +52,7 @@ public Query next() { Id sourceId = this.sources.next(); ConditionQuery query = GraphTransaction.constructEdgesQuery(sourceId, this.directions, - this.labels); + this.labels.toArray(new Id[0])); if (this.limit != Query.NO_LIMIT) { query.limit(this.limit); query.capacity(this.limit); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Query.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Query.java index 4d8e39ccb7..3a024283ff 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Query.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Query.java @@ -139,6 +139,10 @@ public Query originQuery() { return this.originQuery; } + public void setOriginQuery(Query query) { + this.originQuery = query; + } + public Query rootOriginQuery() { Query root = this; while (root.originQuery != null) { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinarySerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinarySerializer.java index 37a7e9a9ca..677ed165f1 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinarySerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BinarySerializer.java @@ -59,6 +59,7 @@ import org.apache.hugegraph.type.define.Cardinality; import org.apache.hugegraph.type.define.DataType; import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.type.define.EdgeLabelType; import org.apache.hugegraph.type.define.Frequency; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.type.define.IdStrategy; @@ -73,6 +74,8 @@ import org.apache.hugegraph.util.StringEncoding; import org.apache.tinkerpop.gremlin.structure.Edge; +import static org.apache.hugegraph.schema.SchemaElement.UNDEF; + public class BinarySerializer extends AbstractSerializer { /* @@ -277,15 +280,26 @@ protected void parseEdge(BackendColumn col, HugeVertex vertex, } byte type = buffer.read(); Id labelId = buffer.readId(); + Id subLabelId = buffer.readId(); String sortValues = buffer.readStringWithEnding(); Id otherVertexId = buffer.readId(); boolean direction = EdgeId.isOutDirectionFromCode(type); - EdgeLabel edgeLabel = graph.edgeLabelOrNone(labelId); - // Construct edge - HugeEdge edge = HugeEdge.constructEdge(vertex, direction, edgeLabel, - sortValues, otherVertexId); + HugeEdge edge; + if (graph == null) { /* when calculation sinking */ + EdgeLabel edgeLabel = new EdgeLabel(null, subLabelId, UNDEF); + if (subLabelId != labelId) { + edgeLabel.edgeLabelType(EdgeLabelType.SUB); + edgeLabel.fatherId(labelId); + } + edge = HugeEdge.constructEdgeWithoutGraph(vertex, direction, edgeLabel, + sortValues, otherVertexId); + } else { + EdgeLabel edgeLabel = graph.edgeLabelOrNone(subLabelId); + edge = HugeEdge.constructEdge(vertex, direction, edgeLabel, + sortValues, otherVertexId); + } // Parse edge-id + edge-properties buffer = BytesBuffer.wrap(col.value); @@ -667,6 +681,11 @@ private Query writeQueryEdgeRangeCondition(ConditionQuery cq) { start.write(direction.type().code()); start.writeId(label); + Id subLabel = cq.condition(HugeKeys.SUB_LABEL); + if (subLabel != null) { + start.writeId(subLabel); + } + BytesBuffer end = BytesBuffer.allocate(BytesBuffer.BUF_EDGE_ID); end.copyFrom(start); @@ -725,6 +744,9 @@ private Query writeQueryEdgePrefixCondition(ConditionQuery cq) { } else if (key == HugeKeys.LABEL) { assert value instanceof Id; buffer.writeId((Id) value); + } else if (key == HugeKeys.SUB_LABEL) { + assert value instanceof Id; + buffer.writeId((Id) value); } else if (key == HugeKeys.SORT_VALUES) { assert value instanceof String; buffer.writeStringWithEnding((String) value); @@ -1104,8 +1126,7 @@ public VertexLabel readVertexLabel(HugeGraph graph, public BinaryBackendEntry writeEdgeLabel(EdgeLabel schema) { this.entry = newBackendEntry(schema); writeString(HugeKeys.NAME, schema.name()); - writeId(HugeKeys.SOURCE_LABEL, schema.sourceLabel()); - writeId(HugeKeys.TARGET_LABEL, schema.targetLabel()); + writeIds(HugeKeys.LINKS, schema.linksIds()); writeEnum(HugeKeys.FREQUENCY, schema.frequency()); writeIds(HugeKeys.PROPERTIES, schema.properties()); writeIds(HugeKeys.SORT_KEYS, schema.sortKeys()); @@ -1127,8 +1148,7 @@ public EdgeLabel readEdgeLabel(HugeGraph graph, String name = readString(HugeKeys.NAME); EdgeLabel edgeLabel = new EdgeLabel(graph, id, name); - edgeLabel.sourceLabel(readId(HugeKeys.SOURCE_LABEL)); - edgeLabel.targetLabel(readId(HugeKeys.TARGET_LABEL)); + edgeLabel.linksIds(readIds(HugeKeys.LINKS)); edgeLabel.frequency(readEnum(HugeKeys.FREQUENCY, Frequency.class)); edgeLabel.properties(readIds(HugeKeys.PROPERTIES)); edgeLabel.sortKeys(readIds(HugeKeys.SORT_KEYS)); @@ -1312,9 +1332,9 @@ private Id readId(byte[] value) { } private byte[] writeIds(Collection ids) { - E.checkState(ids.size() <= BytesBuffer.UINT16_MAX, + E.checkState(ids.size() <= BytesBuffer.MAX_PROPERTIES, "The number of properties of vertex/edge label " + - "can't exceed '%s'", BytesBuffer.UINT16_MAX); + "can't exceed '%s'", BytesBuffer.MAX_PROPERTIES); int size = 2; for (Id id : ids) { size += (1 + id.length()); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BytesBuffer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BytesBuffer.java index b99c2c8b5e..2c890ebe46 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BytesBuffer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/BytesBuffer.java @@ -51,22 +51,27 @@ public final class BytesBuffer extends OutputStream { public static final int CHAR_LEN = Character.BYTES; public static final int FLOAT_LEN = Float.BYTES; public static final int DOUBLE_LEN = Double.BYTES; - public static final int BLOB_LEN = 4; + public static final int BYTES_LEN = 4; + public static final int BLOB_LEN = 5; public static final int UINT8_MAX = ((byte) -1) & 0xff; public static final int UINT16_MAX = ((short) -1) & 0xffff; public static final long UINT32_MAX = (-1) & 0xffffffffL; + // TODO: support user-defined configuration // NOTE: +1 to let code 0 represent length 1 - public static final int ID_LEN_MASK = 0x7f; - public static final int ID_LEN_MAX = 0x7f + 1; // 128 - public static final int BIG_ID_LEN_MAX = 0x7fff + 1; // 32768 + public static final int ID_LEN_MAX = 0x3fff + 1; // 16KB + public static final int EID_LEN_MAX = 64 * 1024; public static final byte STRING_ENDING_BYTE = (byte) 0x00; public static final byte STRING_ENDING_BYTE_FF = (byte) 0xff; - public static final int STRING_LEN_MAX = UINT16_MAX; + + // TODO: support user-defined configuration + public static final long BYTES_LEN_MAX = 10 * Bytes.MB; public static final long BLOB_LEN_MAX = 1 * Bytes.GB; + public static final int MAX_PROPERTIES = BytesBuffer.UINT16_MAX; + // The value must be in range [8, ID_LEN_MAX] public static final int INDEX_HASH_ID_THRESHOLD = 32; @@ -87,8 +92,7 @@ public BytesBuffer() { public BytesBuffer(int capacity) { E.checkArgument(capacity <= MAX_BUFFER_CAPACITY, - "Capacity exceeds max buffer capacity: %s", - MAX_BUFFER_CAPACITY); + "Capacity exceeds max buffer capacity: %s", MAX_BUFFER_CAPACITY); this.buffer = ByteBuffer.allocate(capacity); this.resize = true; } @@ -167,8 +171,7 @@ private void require(int size) { // Extra capacity as buffer int newCapacity = size + this.buffer.limit() + DEFAULT_CAPACITY; E.checkArgument(newCapacity <= MAX_BUFFER_CAPACITY, - "Capacity exceeds max buffer capacity: %s", - MAX_BUFFER_CAPACITY); + "Capacity exceeds max buffer capacity: %s", MAX_BUFFER_CAPACITY); ByteBuffer newBuffer = ByteBuffer.allocate(newCapacity); this.buffer.flip(); newBuffer.put(this.buffer); @@ -288,10 +291,9 @@ public double readDouble() { } public BytesBuffer writeBytes(byte[] bytes) { - E.checkArgument(bytes.length <= UINT16_MAX, - "The max length of bytes is %s, but got %s", - UINT16_MAX, bytes.length); - require(SHORT_LEN + bytes.length); + E.checkArgument(bytes.length <= BYTES_LEN_MAX, "The max length of bytes is %s, but got %s", + BYTES_LEN_MAX, bytes.length); + require(BYTES_LEN + bytes.length); this.writeVInt(bytes.length); this.write(bytes); return this; @@ -304,8 +306,8 @@ public byte[] readBytes() { } public BytesBuffer writeBigBytes(byte[] bytes) { - E.checkArgument(bytes.length <= BLOB_LEN_MAX, - "The max length of bytes is %s, but got %s", + // TODO: note the max blob size should be 128MB (due to MAX_BUFFER_CAPACITY) + E.checkArgument(bytes.length <= BLOB_LEN_MAX, "The max length of bytes is %s, but got %s", BLOB_LEN_MAX, bytes.length); require(BLOB_LEN + bytes.length); this.writeVInt(bytes.length); @@ -346,9 +348,7 @@ public BytesBuffer writeStringWithEnding(String value) { assert !Bytes.contains(bytes, STRING_ENDING_BYTE_FF) : "Invalid UTF8 bytes: " + value; if (Bytes.contains(bytes, STRING_ENDING_BYTE)) { - E.checkArgument(false, - "Can't contains byte '0x00' in string: '%s'", - value); + E.checkArgument(false, "Can't contains byte '0x00' in string: '%s'", value); } this.write(bytes); } @@ -430,8 +430,7 @@ public BytesBuffer writeVInt(int value) { public int readVInt() { byte leading = this.read(); - E.checkArgument(leading != 0x80, - "Unexpected varint with leading byte '0x%s'", + E.checkArgument(leading != 0x80, "Unexpected varint with leading byte '0x%s'", Bytes.toHex(leading)); int value = leading & 0x7f; if (leading >= 0) { @@ -450,8 +449,7 @@ public int readVInt() { } } - E.checkArgument(i < 5, - "Unexpected varint %s with too many bytes(%s)", + E.checkArgument(i < 5, "Unexpected varint %s with too many bytes(%s)", value, i + 1); E.checkArgument(i < 4 || (leading & 0x70) == 0, "Unexpected varint %s with leading byte '0x%s'", @@ -494,8 +492,7 @@ public BytesBuffer writeVLong(long value) { public long readVLong() { byte leading = this.read(); - E.checkArgument(leading != 0x80, - "Unexpected varlong with leading byte '0x%s'", + E.checkArgument(leading != 0x80, "Unexpected varlong with leading byte '0x%s'", Bytes.toHex(leading)); long value = leading & 0x7fL; if (leading >= 0) { @@ -514,8 +511,7 @@ public long readVLong() { } } - E.checkArgument(i < 10, - "Unexpected varlong %s with too many bytes(%s)", + E.checkArgument(i < 10, "Unexpected varlong %s with too many bytes(%s)", value, i + 1); E.checkArgument(i < 9 || (leading & 0x7e) == 0, "Unexpected varlong %s with leading byte '0x%s'", @@ -581,8 +577,7 @@ public void writeProperty(DataType dataType, Object value) { this.writeString((String) value); break; case BLOB: - byte[] bytes = value instanceof byte[] ? - (byte[]) value : ((Blob) value).bytes(); + byte[] bytes = value instanceof byte[] ? (byte[]) value : ((Blob) value).bytes(); this.writeBigBytes(bytes); break; case UUID: @@ -592,6 +587,7 @@ public void writeProperty(DataType dataType, Object value) { this.writeLong(uuid.getLeastSignificantBits()); break; default: + // TODO: replace Kryo with Fury (https://github.com/apache/fury) this.writeBytes(KryoUtil.toKryoWithType(value)); break; } @@ -624,15 +620,12 @@ public Object readProperty(DataType dataType) { case UUID: return new UUID(this.readLong(), this.readLong()); default: + // TODO: replace Kryo with Fury (https://github.com/apache/fury) return KryoUtil.fromKryoWithType(this.readBytes()); } } public BytesBuffer writeId(Id id) { - return this.writeId(id, false); - } - - public BytesBuffer writeId(Id id, boolean big) { switch (id.type()) { case LONG: // Number Id @@ -640,36 +633,33 @@ public BytesBuffer writeId(Id id, boolean big) { this.writeNumber(value); break; case UUID: - // UUID Id + // UUID ID byte[] bytes = id.asBytes(); assert bytes.length == Id.UUID_LENGTH; this.writeUInt8(0x7f); // 0b01111111 means UUID this.write(bytes); break; case EDGE: - // Edge Id + // Edge ID this.writeUInt8(0x7e); // 0b01111110 means EdgeId this.writeEdgeId(id); break; default: - // String Id + // String Id (VertexID) bytes = id.asBytes(); int len = bytes.length; E.checkArgument(len > 0, "Can't write empty id"); - if (!big) { - E.checkArgument(len <= ID_LEN_MAX, - "Id max length is %s, but got %s {%s}", - ID_LEN_MAX, len, id); - len -= 1; // mapping [1, 128] to [0, 127] + E.checkArgument(len <= ID_LEN_MAX, "Big id max length is %s, but got %s {%s}", + ID_LEN_MAX, len, id); + len -= 1; // mapping [1, 16384] to [0, 16383] + if (len <= 0x3f) { + // If length is <= 63, use a single byte with the highest bit set to 1 this.writeUInt8(len | 0x80); } else { - E.checkArgument(len <= BIG_ID_LEN_MAX, - "Big id max length is %s, but got %s {%s}", - BIG_ID_LEN_MAX, len, id); - len -= 1; int high = len >> 8; int low = len & 0xff; - this.writeUInt8(high | 0x80); + // Write high 8 bits with highest two bits set to 11 + this.writeUInt8(high | 0xc0); this.writeUInt8(low); } this.write(bytes); @@ -679,10 +669,6 @@ public BytesBuffer writeId(Id id, boolean big) { } public Id readId() { - return this.readId(false); - } - - public Id readId(boolean big) { byte b = this.read(); boolean number = (b & 0x80) == 0; if (number) { @@ -698,24 +684,25 @@ public Id readId(boolean big) { } } else { // String Id - int len = b & ID_LEN_MASK; - if (big) { + int len = b & 0x3f; // Take the lowest 6 bits as part of the length + if ((b & 0x40) != 0) { // If the 7th bit is set, length information spans 2 bytes int high = len << 8; int low = this.readUInt8(); len = high + low; } - len += 1; // restore [0, 127] to [1, 128] + len += 1; // restore [0, 16383] to [1, 16384] byte[] id = this.read(len); return IdGenerator.of(id, IdType.STRING); } } public BytesBuffer writeEdgeId(Id id) { - // owner-vertex + dir + edge-label + sort-values + other-vertex + // owner-vertex + dir + edge-label + sub-edge-label + sort-values + other-vertex EdgeId edge = (EdgeId) id; this.writeId(edge.ownerVertexId()); this.write(edge.directionCode()); this.writeId(edge.edgeLabelId()); + this.writeId(edge.subLabelId()); this.writeStringWithEnding(edge.sortValues()); this.writeId(edge.otherVertexId()); return this; @@ -723,7 +710,7 @@ public BytesBuffer writeEdgeId(Id id) { public Id readEdgeId() { return new EdgeId(this.readId(), EdgeId.directionFromCode(this.read()), - this.readId(), this.readStringWithEnding(), + this.readId(), this.readId(), this.readStringWithEnding(), this.readId()); } @@ -739,12 +726,11 @@ public BytesBuffer writeIndexId(Id id, HugeType type, boolean withEnding) { this.write(bytes); if (type.isStringIndex()) { if (Bytes.contains(bytes, STRING_ENDING_BYTE)) { - // Not allow STRING_ENDING_BYTE exist in string index id + // Not allow STRING_ENDING_BYTE to exist in string index id E.checkArgument(false, "The %s type index id can't contains " + - "byte '0x%s', but got: 0x%s", type, - Bytes.toHex(STRING_ENDING_BYTE), - Bytes.toHex(bytes)); + "byte '0x%s', but got: 0x%s", + type, Bytes.toHex(STRING_ENDING_BYTE), Bytes.toHex(bytes)); } if (withEnding) { this.writeStringWithEnding(""); @@ -806,12 +792,9 @@ public BinaryId parseOlapId(HugeType type, boolean isOlap) { } // Parse id from bytes int start = this.buffer.position(); - /** - * OLAP - * {PropertyKey}{VertexId} - */ + // OLAP {PropertyKey}{VertexId} if (isOlap) { - // First read olap property id + // Read olap property id first Id pkId = this.readId(); } Id id = this.readId(); @@ -890,8 +873,7 @@ private void writeNumber(long val) { } private long readNumber(byte b) { - E.checkArgument((b & 0x80) == 0, - "Not a number type with prefix byte '0x%s'", + E.checkArgument((b & 0x80) == 0, "Not a number type with prefix byte '0x%s'", Bytes.toHex(b)); // Parse the kind from byte 0kkksxxx int kind = b >>> 4; @@ -948,8 +930,7 @@ private byte[] readBytesWithEnding() { break; } } - E.checkArgument(foundEnding, "Not found ending '0x%s'", - Bytes.toHex(STRING_ENDING_BYTE)); + E.checkArgument(foundEnding, "Not found ending '0x%s'", Bytes.toHex(STRING_ENDING_BYTE)); int end = this.buffer.position() - 1; int len = end - start; if (len <= 0) { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializer.java index f5c31d26fd..a2e3279976 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializer.java @@ -61,6 +61,9 @@ import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.JsonUtil; +/** + * without father and sub edge label + */ public abstract class TableSerializer extends AbstractSerializer { public TableSerializer(HugeConfig config) { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializerV2.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializerV2.java new file mode 100644 index 0000000000..54f9e4cf54 --- /dev/null +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TableSerializerV2.java @@ -0,0 +1,129 @@ +/* + * 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.backend.serializer; + +import org.apache.hugegraph.HugeGraph; +import org.apache.hugegraph.backend.id.EdgeId; +import org.apache.hugegraph.backend.id.Id; +import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.backend.store.BackendEntry; +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.schema.VertexLabel; +import org.apache.hugegraph.structure.HugeEdge; +import org.apache.hugegraph.structure.HugeEdgeProperty; +import org.apache.hugegraph.structure.HugeVertex; +import org.apache.hugegraph.type.define.HugeKeys; + +/** + * with father and sub edge label + */ +public abstract class TableSerializerV2 extends TableSerializer { + + public TableSerializerV2(HugeConfig config) { + super(config); + } + + @Override + protected TableBackendEntry.Row formatEdge(HugeEdge edge) { + EdgeId id = edge.idWithDirection(); + TableBackendEntry.Row row = new TableBackendEntry.Row(edge.type(), id); + if (edge.hasTtl()) { + row.ttl(edge.ttl()); + row.column(HugeKeys.EXPIRED_TIME, edge.expiredTime()); + } + // Id: ownerVertex + direction + edge-label + sub-edge-label + sortValues + otherVertex + row.column(HugeKeys.OWNER_VERTEX, this.writeId(id.ownerVertexId())); + row.column(HugeKeys.DIRECTION, id.directionCode()); + row.column(HugeKeys.LABEL, id.edgeLabelId().asLong()); + row.column(HugeKeys.SUB_LABEL, id.subLabelId().asLong()); + row.column(HugeKeys.SORT_VALUES, id.sortValues()); + row.column(HugeKeys.OTHER_VERTEX, this.writeId(id.otherVertexId())); + + this.formatProperties(edge, row); + return row; + } + + /** + * Parse an edge from a entry row + * + * @param row edge entry + * @param vertex null or the source vertex + * @param graph the HugeGraph context object + * @return the source vertex + */ + @Override + protected HugeEdge parseEdge(TableBackendEntry.Row row, + HugeVertex vertex, HugeGraph graph) { + Object ownerVertexId = row.column(HugeKeys.OWNER_VERTEX); + Number dir = row.column(HugeKeys.DIRECTION); + boolean direction = EdgeId.isOutDirectionFromCode(dir.byteValue()); + Number label = row.column(HugeKeys.LABEL); + Number subLabel = row.column(HugeKeys.SUB_LABEL); + String sortValues = row.column(HugeKeys.SORT_VALUES); + Object otherVertexId = row.column(HugeKeys.OTHER_VERTEX); + Number expiredTime = row.column(HugeKeys.EXPIRED_TIME); + + if (vertex == null) { + Id ownerId = this.readId(ownerVertexId); + vertex = new HugeVertex(graph, ownerId, VertexLabel.NONE); + } + + EdgeLabel edgeLabel = graph.edgeLabelOrNone(this.toId(label)); + EdgeLabel subEdgeLabel = graph.edgeLabelOrNone(this.toId(subLabel)); + Id otherId = this.readId(otherVertexId); + + // Construct edge + HugeEdge edge = HugeEdge.constructEdge(vertex, direction, subEdgeLabel, + sortValues, otherId); + + // Parse edge properties + this.parseProperties(edge, row); + + // The expired time is null when the edge is non-ttl + long expired = edge.hasTtl() ? expiredTime.longValue() : 0L; + edge.expiredTime(expired); + + return edge; + } + + @Override + public BackendEntry writeEdgeProperty(HugeEdgeProperty prop) { + HugeEdge edge = prop.element(); + EdgeId id = edge.idWithDirection(); + TableBackendEntry.Row row = new TableBackendEntry.Row(edge.type(), id); + if (edge.hasTtl()) { + row.ttl(edge.ttl()); + row.column(HugeKeys.EXPIRED_TIME, edge.expiredTime()); + } + // Id: ownerVertex + direction + edge-label + sub-edge-label + sortValues + otherVertex + row.column(HugeKeys.OWNER_VERTEX, this.writeId(id.ownerVertexId())); + row.column(HugeKeys.DIRECTION, id.directionCode()); + row.column(HugeKeys.LABEL, id.edgeLabelId().asLong()); + row.column(HugeKeys.SUB_LABEL, id.subLabelId().asLong()); + row.column(HugeKeys.SORT_VALUES, id.sortValues()); + row.column(HugeKeys.OTHER_VERTEX, this.writeId(id.otherVertexId())); + + // Format edge property + this.formatProperty(prop, row); + + TableBackendEntry entry = newBackendEntry(row); + entry.subId(IdGenerator.of(prop.key())); + return entry; + } +} diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextSerializer.java index 5a39aeaeaf..2d5cb81ec1 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/TextSerializer.java @@ -223,11 +223,12 @@ private void parseEdge(String colName, String colValue, HugeGraph graph = vertex.graph(); boolean direction = colParts[0].equals(EDGE_OUT_TYPE); - String sortValues = readEdgeName(colParts[2]); + String sortValues = readEdgeName(colParts[3]); EdgeLabel edgeLabel = graph.edgeLabelOrNone(readId(colParts[1])); - Id otherVertexId = readEntryId(colParts[3]); + EdgeLabel subEdgeLabel = graph.edgeLabelOrNone(readId(colParts[2])); + Id otherVertexId = readEntryId(colParts[4]); // Construct edge - HugeEdge edge = HugeEdge.constructEdge(vertex, direction, edgeLabel, + HugeEdge edge = HugeEdge.constructEdge(vertex, direction, subEdgeLabel, sortValues, otherVertexId); String[] valParts = colValue.split(VALUE_SPLITOR); @@ -772,6 +773,7 @@ private String writeEdgeId(Id id, boolean withOwnerVertex) { // Edge name: type + edge-label-name + sortKeys + targetVertex list.add(writeType(edgeId.direction().type())); list.add(writeId(edgeId.edgeLabelId())); + list.add(writeId(edgeId.subLabelId())); list.add(writeEdgeName(edgeId.sortValues())); list.add(writeEntryId(edgeId.otherVertexId())); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStore.java index 2ef9a6db73..adb3c8c400 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/AbstractBackendStore.java @@ -17,8 +17,24 @@ package org.apache.hugegraph.backend.store; +import org.apache.hugegraph.HugeGraph; +import org.apache.hugegraph.backend.query.Condition; +import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.backend.query.ConditionQueryFlatten; +import org.apache.hugegraph.backend.query.Query; import org.apache.hugegraph.exception.ConnectionException; +import org.apache.hugegraph.iterator.ExtendableIterator; +import org.apache.hugegraph.iterator.FlatMapperIterator; import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.Directions; +import org.apache.hugegraph.type.define.HugeKeys; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.function.Function; public abstract class AbstractBackendStore implements BackendStore { @@ -36,6 +52,57 @@ protected MetaDispatcher metaDispatcher() { return this.dispatcher; } + protected List getHugeTypes(Query sampleQuery) { + Set typeSet = new HashSet<>(); + for (Condition c : sampleQuery.conditions()) { + if (c.isRelation() && c.isSysprop()) { + Condition.SyspropRelation sr = (Condition.SyspropRelation) c; + if (sr.relation() == Condition.RelationType.EQ) { + if (sr.key().equals(HugeKeys.DIRECTION)) { + typeSet.add(((Directions) sr.value()).type()); + } + } + } else if (c.type() == Condition.ConditionType.OR && c.isSysprop()) { + for (Condition.Relation r : c.relations()) { + if (r.relation() == Condition.RelationType.EQ) { + if (r.key().equals(HugeKeys.DIRECTION)) { + typeSet.add(((Directions) r.value()).type()); + } + } + } + } + } + return new ArrayList<>(typeSet); + } + + @Override + public Iterator> query(Iterator queries, + Function queryWriter, + HugeGraph hugeGraph) { + List> result = new ArrayList<>(); + + FlatMapperIterator it = + new FlatMapperIterator<>(queries, query -> { + assert query instanceof ConditionQuery; + List flattenQueryList = + ConditionQueryFlatten.flatten((ConditionQuery) query); + + if (flattenQueryList.size() > 1) { + ExtendableIterator itExtend + = new ExtendableIterator<>(); + flattenQueryList.forEach(cq -> { + Query cQuery = queryWriter.apply(cq); + itExtend.extend(this.query(cQuery)); + }); + return itExtend; + } else { + return this.query(queryWriter.apply(query)); + } + }); + result.add(it); + return result.iterator(); + } + public void registerMetaHandler(String name, MetaHandler handler) { this.dispatcher.registerMetaHandler(name, handler); } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java index f13798dd63..20469f77aa 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java @@ -94,7 +94,7 @@ public Object metadata(String meta, Object... args) { public static final void checkInterrupted() { if (Thread.interrupted()) { - throw new BackendException("Interrupted, maybe it is timed out", + throw new BackendException("Interrupted, maybe it is timed out or uses too much memory", new InterruptedException()); } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendFeatures.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendFeatures.java index 90001cc1e7..c6060944f0 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendFeatures.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendFeatures.java @@ -31,7 +31,13 @@ default boolean supportsSnapshot() { return false; } - default boolean supportsTaskAndServerVertex() { return false; } + default boolean supportsTaskAndServerVertex() { + return false; + } + + default boolean supportsFatherAndSubEdgeLabel() { + return true; + } boolean supportsScanToken(); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendStore.java index 5c05e37c5a..6486d353c1 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendStore.java @@ -19,7 +19,9 @@ import java.util.Iterator; import java.util.Map; +import java.util.function.Function; +import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.backend.id.Id; import org.apache.hugegraph.backend.id.IdGenerator; import org.apache.hugegraph.backend.query.Query; @@ -70,6 +72,11 @@ public interface BackendStore { // Query data Iterator query(Query query); + // TODO: unused now + Iterator> query(Iterator queries, + Function queryWriter, + HugeGraph hugeGraph); + Number queryNumber(Query query); // Transaction diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTables.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTables.java index 19321a5514..445c28a5d6 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTables.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/memory/InMemoryDBTables.java @@ -237,23 +237,62 @@ protected Map queryByFilter( } // Only support querying edge by label - E.checkState(conditions.size() == 1, - "Not support querying edge by %s", conditions); - Condition cond = conditions.iterator().next(); - E.checkState(cond.isRelation(), - "Not support querying edge by %s", conditions); - Condition.Relation relation = (Condition.Relation) cond; - E.checkState(relation.key().equals(HugeKeys.LABEL), - "Not support querying edge by %s", conditions); - String label = (String) relation.serialValue(); + if (conditions.size() == 1) { + E.checkState(conditions.size() == 1, + "Not support querying edge by %s", conditions); + Condition cond = conditions.iterator().next(); + E.checkState(cond.isRelation(), + "Not support querying edge by %s", conditions); + Condition.Relation relation = (Condition.Relation) cond; + E.checkState(relation.key().equals(HugeKeys.LABEL), + "Not support querying edge by %s", conditions); + String label = (String) relation.serialValue(); + String out = EdgeId.concat(HugeType.EDGE_OUT.string(), label); + String in = EdgeId.concat(HugeType.EDGE_IN.string(), label); + return queryByFilterInternal(out, in, entries); + } else { + E.checkState(conditions.size() == 2, + "Not support querying edge by %s", conditions); + Iterator conditionIterator = conditions.iterator(); + + Condition cond1 = conditionIterator.next(); + E.checkState(cond1.isRelation(), + "Not support querying edge by %s", conditions); + Condition.Relation relation1 = (Condition.Relation) cond1; + Condition cond2 = conditionIterator.next(); + E.checkState(cond2.isRelation(), + "Not support querying edge by %s", conditions); + Condition.Relation relation2 = (Condition.Relation) cond2; + + if (relation1.key().equals(HugeKeys.LABEL) && relation2.key().equals(HugeKeys.SUB_LABEL)) { + String label = (String) relation1.serialValue(); + String subLabel = (String) relation2.serialValue(); + String out = EdgeId.concat(HugeType.EDGE_OUT.string(), label, subLabel); + String in = EdgeId.concat(HugeType.EDGE_IN.string(), label, subLabel); + return queryByFilterInternal(out, in, entries); + } else if (relation2.key().equals(HugeKeys.LABEL) && relation1.key().equals(HugeKeys.SUB_LABEL)) { + String label = (String) relation2.serialValue(); + String subLabel = (String) relation1.serialValue(); + String out = EdgeId.concat(HugeType.EDGE_OUT.string(), label, subLabel); + String in = EdgeId.concat(HugeType.EDGE_IN.string(), label, subLabel); + return queryByFilterInternal(out, in, entries); + } else { + E.checkState(false, "Not support querying edge by %s", conditions); + } + } + return entries; + } + + private Map queryByFilterInternal( + String out, String in, + Map entries) { Map rs = InsertionOrderUtil.newMap(); for (BackendEntry value : entries.values()) { // TODO: Compatible with BackendEntry TextBackendEntry entry = (TextBackendEntry) value; - String out = EdgeId.concat(HugeType.EDGE_OUT.string(), label); - String in = EdgeId.concat(HugeType.EDGE_IN.string(), label); + if (entry.containsPrefix(out)) { BackendEntry edges = new TextBackendEntry(HugeType.VERTEX, entry.id()); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStore.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStore.java index bf89c6b17a..1765562127 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStore.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/raft/RaftBackendStore.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.function.Function; +import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.backend.BackendException; import org.apache.hugegraph.backend.query.Query; import org.apache.hugegraph.backend.store.BackendEntry; @@ -152,6 +153,13 @@ public Iterator query(Query query) { this.queryByRaft(query, o -> this.store.query(query)); } + @Override + public Iterator> query(Iterator queries, + Function queryWriter, + HugeGraph hugeGraph) { + throw new UnsupportedOperationException("unimplemented for RaftBackendStore"); + } + @Override public Number queryNumber(Query query) { return (Number) diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java index 3905ebb0cc..ddf942ec32 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java @@ -67,6 +67,7 @@ import org.apache.hugegraph.job.EphemeralJob; import org.apache.hugegraph.job.system.DeleteExpiredJob; import org.apache.hugegraph.perf.PerfUtil.Watched; +import org.apache.hugegraph.schema.EdgeLabel; import org.apache.hugegraph.schema.IndexLabel; import org.apache.hugegraph.schema.PropertyKey; import org.apache.hugegraph.schema.SchemaLabel; @@ -147,6 +148,17 @@ public void updateLabelIndex(HugeElement element, boolean removed) { } else { this.doAppend(this.serializer.writeIndex(index)); } + + if (element instanceof HugeEdge && ((EdgeLabel) label).hasFather()) { + HugeIndex fatherIndex = new HugeIndex(this.graph(), IndexLabel.label(element.type())); + fatherIndex.fieldValues(((EdgeLabel) label).fatherId()); + fatherIndex.elementIds(element.id(), element.expiredTime()); + if (removed) { + this.doEliminate(this.serializer.writeIndex(fatherIndex)); + } else { + this.doAppend(this.serializer.writeIndex(fatherIndex)); + } + } } @Watched(prefix = "index") @@ -167,6 +179,13 @@ public void updateEdgeIndex(HugeEdge edge, boolean removed) { for (Id id : edge.schemaLabel().indexLabels()) { this.updateIndex(id, edge, removed); } + + EdgeLabel label = edge.schemaLabel(); + if (label.hasFather()) { + for (Id id : graph().edgeLabel(label.fatherId()).indexLabels()) { + this.updateIndex(id, edge, removed); + } + } } private void updateVertexOlapIndex(HugeVertex vertex, boolean removed) { diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphTransaction.java index 10aa73f719..ccd2b5405f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphTransaction.java @@ -20,16 +20,21 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.google.common.collect.Iterators; import org.apache.commons.collections.CollectionUtils; import org.apache.hugegraph.HugeException; @@ -70,6 +75,7 @@ import org.apache.hugegraph.schema.EdgeLabel; import org.apache.hugegraph.schema.IndexLabel; import org.apache.hugegraph.schema.PropertyKey; +import org.apache.hugegraph.schema.SchemaElement; import org.apache.hugegraph.schema.SchemaLabel; import org.apache.hugegraph.schema.VertexLabel; import org.apache.hugegraph.structure.HugeEdge; @@ -370,7 +376,7 @@ protected void prepareDeletions(Map removedVertices, continue; } // Query all edges of the vertex and remove them - Query query = constructEdgesQuery(v.id(), Directions.BOTH); + Query query = constructEdgesQuery(v.id(), Directions.BOTH, new Id[0]); Iterator vedges = this.queryEdgesFromBackend(query); try { while (vedges.hasNext()) { @@ -913,7 +919,7 @@ public void removeEdge(HugeEdge edge) { } public Iterator queryEdgesByVertex(Id id) { - return this.queryEdges(constructEdgesQuery(id, Directions.BOTH)); + return this.queryEdges(constructEdgesQuery(id, Directions.BOTH, new Id[0])); } public Iterator queryEdges(Object... edgeIds) { @@ -1044,6 +1050,38 @@ public Iterator queryEdges(Query query) { protected Iterator queryEdgesFromBackend(Query query) { assert query.resultType().isEdge(); + if (query instanceof ConditionQuery && !query.paging()) { + // TODO: support: paging + parent label + boolean supportIn = this.storeFeatures().supportsQueryWithInCondition(); + // consider multi labels + properties, see org.apache.hugegraph.core.EdgeCoreTest.testQueryInEdgesOfVertexByLabels + Stream flattenedQueries = ConditionQueryFlatten.flatten((ConditionQuery) query, supportIn).stream(); + + Stream> edgeIterators = flattenedQueries.map(cq -> { + Id label = cq.condition(HugeKeys.LABEL); + if (this.storeFeatures().supportsFatherAndSubEdgeLabel() && + label != null && + graph().edgeLabel(label).isFather() && + cq.condition(HugeKeys.SUB_LABEL) == null && + cq.condition(HugeKeys.OWNER_VERTEX) != null && + cq.condition(HugeKeys.DIRECTION) != null && + matchEdgeSortKeys(cq, false, this.graph())) { + // g.V("V.id").outE("parentLabel").has("sortKey","value") + return parentElQueryWithSortKeys( + graph().edgeLabel(label), graph().edgeLabels(), cq); + } else { + return queryEdgesFromBackendInternal(cq); + } + }); + + return edgeIterators.reduce(ExtendableIterator::concat).orElse(Collections.emptyIterator()); + } + + return queryEdgesFromBackendInternal(query); + } + + private Iterator queryEdgesFromBackendInternal(Query query) { + assert query.resultType().isEdge(); + QueryResults results = this.query(query); Iterator entries = results.iterator(); @@ -1070,6 +1108,20 @@ protected Iterator queryEdgesFromBackend(Query query) { return edges; } + private Iterator parentElQueryWithSortKeys(EdgeLabel label, + Collection allEls, + ConditionQuery cq) { + return allEls.stream() + .filter(el -> el.edgeLabelType().sub() && el.fatherId().equals(label.id())) + .map(el -> { + ConditionQuery tempQuery = cq.copy(); + tempQuery.eq(HugeKeys.SUB_LABEL, el.id()); + return this.queryEdgesFromBackend(tempQuery); + }) + .reduce(Iterators::concat) + .orElse(Collections.emptyIterator()); + } + @Watched(prefix = "graph") public void addVertexProperty(HugeVertexProperty prop) { // NOTE: this method can also be used to update property @@ -1238,6 +1290,13 @@ public void removeEdgeProperty(HugeEdgeProperty prop) { public static ConditionQuery constructEdgesQuery(Id sourceVertex, Directions direction, Id... edgeLabels) { + return constructEdgesQuery(sourceVertex, direction, List.of(edgeLabels)); + } + + @Watched + public static ConditionQuery constructEdgesQuery(Id sourceVertex, + Directions direction, + EdgeLabel... edgeLabels) { E.checkState(sourceVertex != null, "The edge query must contain source vertex"); E.checkState(direction != null, @@ -1260,16 +1319,25 @@ public static ConditionQuery constructEdgesQuery(Id sourceVertex, // Edge labels if (edgeLabels.length == 1) { - query.eq(HugeKeys.LABEL, edgeLabels[0]); - } else if (edgeLabels.length > 1) { - query.query(Condition.in(HugeKeys.LABEL, - Arrays.asList(edgeLabels))); + EdgeLabel edgeLabel = edgeLabels[0]; + if (edgeLabel.hasFather()) { + query.eq(HugeKeys.LABEL, edgeLabel.fatherId()); + query.eq(HugeKeys.SUB_LABEL, edgeLabel.id()); + } else { + query.eq(HugeKeys.LABEL, edgeLabel.id()); + } + } else if (edgeLabels.length >= 1) { + query.query( + Condition.in(HugeKeys.LABEL, + Arrays.stream(edgeLabels) + .map(SchemaElement::id) + .collect(Collectors.toList()))); } return query; } - public static ConditionQuery constructEdgesQuery(Id sourceVertex, + private static ConditionQuery constructEdgesQuery(Id sourceVertex, Directions direction, List edgeLabels) { E.checkState(sourceVertex != null, @@ -1522,7 +1590,8 @@ private Query optimizeQuery(ConditionQuery query) { query.optimized(OptimizedType.SORT_KEYS); query = query.copy(); // Serialize sort-values - List keys = this.graph().edgeLabel(label).sortKeys(); + EdgeLabel el = this.graph().edgeLabel(label); + List keys = el.sortKeys(); List conditions = GraphIndexTransaction .constructShardConditions(query, keys, HugeKeys.SORT_VALUES); query.query(conditions); @@ -1532,6 +1601,9 @@ private Query optimizeQuery(ConditionQuery query) { */ query.resetUserpropConditions(); + if (this.storeFeatures().supportsFatherAndSubEdgeLabel() && query.condition(HugeKeys.SUB_LABEL) == null) { + query.eq(HugeKeys.SUB_LABEL, el.id()); + } LOG.debug("Query edges by sortKeys: {}", query); return query; } @@ -1546,6 +1618,19 @@ private Query optimizeQuery(ConditionQuery query) { if (query.resultType().isVertex()) { verifyVerticesConditionQuery(query); } else if (query.resultType().isEdge()) { + // fix org.apache.hugegraph.api.traverser.EdgeExistenceAPITest#testEdgeExistenceGet + // add sub label if only the sub label is missing + ConditionQuery finalQuery = query; + if (this.storeFeatures().supportsFatherAndSubEdgeLabel() && + query.condition(HugeKeys.SUB_LABEL) == null && + Arrays.stream(EdgeId.KEYS) + .filter(key -> !Objects.equals(key, HugeKeys.SUB_LABEL)) + .allMatch(key -> finalQuery.condition(key) != null)) { + EdgeLabel el = this.graph().edgeLabel(label); + if (!el.isFather()) { + query.eq(HugeKeys.SUB_LABEL, el.id()); + } + } verifyEdgesConditionQuery(query); } /* @@ -1555,6 +1640,15 @@ private Query optimizeQuery(ConditionQuery query) { */ boolean byLabel = (label != null && query.conditionsSize() == 1); if (!byLabel || this.store().features().supportsQueryByLabel()) { + if (this.storeFeatures().supportsFatherAndSubEdgeLabel() && byLabel && query.resultType().isEdge()) { + // for memory backend + EdgeLabel edgeLabel = graph().edgeLabel(label); + if (edgeLabel.hasFather()) { + query.resetConditions(); + query.eq(HugeKeys.LABEL, edgeLabel.fatherId()); + query.eq(HugeKeys.SUB_LABEL, edgeLabel.id()); + } + } return query; } } @@ -1815,6 +1909,24 @@ private boolean rightResultFromIndexQuery(Query query, HugeElement elem) { } ConditionQuery cq = (ConditionQuery) query; + if (cq.condition(HugeKeys.LABEL) != null && cq.resultType().isEdge()) { + if (cq.conditions().size() == 1) { + // g.E().hasLabel(xxx) + return true; + } + if (cq.optimized() == OptimizedType.INDEX) { + // g.E().hasLabel(xxx).has(yyy) + // consider OptimizedType.INDEX_FILTER occurred in org.apache.hugegraph.core.EdgeCoreTest.testQueryCount + try { + this.indexTx.asyncRemoveIndexLeft(cq, elem); + } catch (Throwable e) { + LOG.warn("Failed to remove left index for query '{}', " + + "element '{}'", cq, elem, e); + } + return true; + } + } + if (cq.optimized() == OptimizedType.NONE || cq.test(elem)) { if (cq.existLeftIndex(elem.id())) { /* diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransaction.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransaction.java index 1d7f595f0d..d58bfcdc0e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransaction.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransaction.java @@ -247,9 +247,21 @@ public EdgeLabel getEdgeLabel(String name) { @Watched(prefix = "schema") public Id removeEdgeLabel(Id id) { LOG.debug("SchemaTransaction remove edge label '{}'", id); - SchemaJob callable = new EdgeLabelRemoveJob(); EdgeLabel schema = this.getEdgeLabel(id); - return asyncRun(this.graph(), schema, callable); + if (schema.edgeLabelType().parent()) { + List edgeLabels = this.getEdgeLabels(); + for (EdgeLabel edgeLabel : edgeLabels) { + if (edgeLabel.edgeLabelType().sub() && + edgeLabel.fatherId() == id) { + throw new NotAllowException( + "Not allowed to remove a parent edge label: '%s' " + + "because the sub edge label '%s' is still existing", + schema.name(), edgeLabel.name()); + } + } + } + SchemaJob job = new EdgeLabelRemoveJob(); + return asyncRun(this.graph(), schema, job); } @Watched(prefix = "schema") diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransactionV2.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransactionV2.java index 8bf0a68b20..903bfade68 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransactionV2.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/SchemaTransactionV2.java @@ -288,19 +288,18 @@ public Id removeEdgeLabel(Id id) { */ LOG.debug("SchemaTransaction remove edge label '{}'", id); EdgeLabel schema = this.getEdgeLabel(id); - // TODO: uncomment later - sub edge labels - //if (schema.edgeLabelType().parent()) { - // List edgeLabels = this.getEdgeLabels(); - // for (EdgeLabel edgeLabel : edgeLabels) { - // if (edgeLabel.edgeLabelType().sub() && - // edgeLabel.fatherId() == id) { - // throw new NotAllowException( - // "Not allowed to remove a parent edge label: '%s' " + - // "because the sub edge label '%s' is still existing", - // schema.name(), edgeLabel.name()); - // } - // } - //} + if (schema.edgeLabelType().parent()) { + List edgeLabels = this.getEdgeLabels(); + for (EdgeLabel edgeLabel : edgeLabels) { + if (edgeLabel.edgeLabelType().sub() && + edgeLabel.fatherId() == id) { + throw new NotAllowException( + "Not allowed to remove a parent edge label: '%s' " + + "because the sub edge label '%s' is still existing", + schema.name(), edgeLabel.name()); + } + } + } SchemaJob job = new EdgeLabelRemoveJob(); return asyncRun(this.graph(), schema, job); } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/GraphSONSchemaSerializer.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/GraphSONSchemaSerializer.java index b92d506532..31d197c099 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/GraphSONSchemaSerializer.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/GraphSONSchemaSerializer.java @@ -20,12 +20,15 @@ import java.util.LinkedHashMap; import java.util.Map; +import com.google.common.collect.ImmutableList; + import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.schema.EdgeLabel; import org.apache.hugegraph.schema.IndexLabel; import org.apache.hugegraph.schema.PropertyKey; import org.apache.hugegraph.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.EdgeLabelType; import org.apache.hugegraph.type.define.HugeKeys; public class GraphSONSchemaSerializer { @@ -64,25 +67,43 @@ public Map writeEdgeLabel(EdgeLabel edgeLabel) { Map map = new LinkedHashMap<>(); map.put(HugeKeys.ID, edgeLabel.id().asLong()); map.put(HugeKeys.NAME, edgeLabel.name()); - map.put(HugeKeys.SOURCE_LABEL, edgeLabel.sourceLabelName()); - map.put(HugeKeys.TARGET_LABEL, edgeLabel.targetLabelName()); - map.put(HugeKeys.FREQUENCY, edgeLabel.frequency()); - map.put(HugeKeys.SORT_KEYS, - graph.mapPkId2Name(edgeLabel.sortKeys())); - map.put(HugeKeys.NULLABLE_KEYS, - graph.mapPkId2Name(edgeLabel.nullableKeys())); - map.put(HugeKeys.INDEX_LABELS, - graph.mapIlId2Name(edgeLabel.indexLabels())); - map.put(HugeKeys.PROPERTIES, - graph.mapPkId2Name(edgeLabel.properties())); - map.put(HugeKeys.STATUS, edgeLabel.status()); - map.put(HugeKeys.TTL, edgeLabel.ttl()); - String ttlStartTimeName = edgeLabel.ttlStartTimeName(); - if (ttlStartTimeName != null) { - map.put(HugeKeys.TTL_START_TIME, ttlStartTimeName); + if (edgeLabel.isFather()) { + map.put(HugeKeys.EDGELABEL_TYPE, EdgeLabelType.PARENT); + if (edgeLabel.links().size() > 0) { + map.put(HugeKeys.LINKS, + graph.mapPairId2Name(edgeLabel.links())); + } + } else if (edgeLabel.hasFather()) { + map.put(HugeKeys.EDGELABEL_TYPE, EdgeLabelType.SUB); + map.put(HugeKeys.PARENT_LABEL, + graph.mapElId2Name(ImmutableList.of(edgeLabel.fatherId())) + .get(0)); + } else { + map.put(HugeKeys.EDGELABEL_TYPE, edgeLabel.edgeLabelType()); } - map.put(HugeKeys.ENABLE_LABEL_INDEX, edgeLabel.enableLabelIndex()); - map.put(HugeKeys.USER_DATA, edgeLabel.userdata()); + + if (!edgeLabel.isFather()) { + map.put(HugeKeys.LINKS, + graph.mapPairId2Name(edgeLabel.links())); + map.put(HugeKeys.FREQUENCY, edgeLabel.frequency()); + map.put(HugeKeys.SORT_KEYS, + graph.mapPkId2Name(edgeLabel.sortKeys())); + map.put(HugeKeys.NULLABLE_KEYS, + graph.mapPkId2Name(edgeLabel.nullableKeys())); + map.put(HugeKeys.INDEX_LABELS, + graph.mapIlId2Name(edgeLabel.indexLabels())); + map.put(HugeKeys.PROPERTIES, + graph.mapPkId2Name(edgeLabel.properties())); + map.put(HugeKeys.STATUS, edgeLabel.status()); + map.put(HugeKeys.TTL, edgeLabel.ttl()); + String ttlStartTimeName = edgeLabel.ttlStartTimeName(); + if (ttlStartTimeName != null) { + map.put(HugeKeys.TTL_START_TIME, ttlStartTimeName); + } + map.put(HugeKeys.ENABLE_LABEL_INDEX, edgeLabel.enableLabelIndex()); + map.put(HugeKeys.USER_DATA, edgeLabel.userdata()); + } + return map; } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/EdgeLabel.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/EdgeLabel.java index b9fac4643a..da572321c1 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/EdgeLabel.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/EdgeLabel.java @@ -21,11 +21,13 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import org.apache.commons.lang3.tuple.Pair; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.backend.id.Id; import org.apache.hugegraph.backend.id.IdGenerator; @@ -43,11 +45,14 @@ public class EdgeLabel extends SchemaLabel { public static final EdgeLabel NONE = new EdgeLabel(null, NONE_ID, UNDEF); + private Set> links = new HashSet<>(); private Id sourceLabel = NONE_ID; private Id targetLabel = NONE_ID; private Frequency frequency; private List sortKeys; - private EdgeLabelType edgeLabelType; + + private EdgeLabelType edgeLabelType = EdgeLabelType.NORMAL; + private Id fatherId; public EdgeLabel(final HugeGraph graph, Id id, String name) { super(graph, id, name); @@ -60,14 +65,34 @@ public HugeType type() { return HugeType.EDGE_LABEL; } - public Frequency frequency() { - return this.frequency; + public boolean isFather() { + return this.edgeLabelType.parent(); } public void edgeLabelType(EdgeLabelType type) { this.edgeLabelType = type; } + public EdgeLabelType edgeLabelType() { + return this.edgeLabelType; + } + + public boolean hasFather() { + return this.edgeLabelType.sub(); + } + + public Id fatherId() { + return this.fatherId; + } + + public void fatherId(Id fatherId) { + this.fatherId = fatherId; + } + + public Frequency frequency() { + return this.frequency; + } + public void frequency(Frequency frequency) { this.frequency = frequency; } @@ -78,53 +103,112 @@ public boolean directed() { } public String sourceLabelName() { - return this.graph.vertexLabelOrNone(this.sourceLabel).name(); + E.checkState(this.links.size() == 1, + "Only edge label has single vertex label pair can call " + + "sourceLabelName(), but current edge label got %s", + this.links.size()); + return this.graph.vertexLabelOrNone(this.links.iterator().next().getLeft()).name(); + } + + public List linksIds() { + List ids = new ArrayList<>(this.links.size() * 2); + for (Pair link : this.links) { + ids.add(link.getLeft()); + ids.add(link.getRight()); + } + return ids; + } + + public void linksIds(Id[] ids) { + this.links = new HashSet<>(ids.length / 2); + for (int i = 0; i < ids.length; i += 2) { + this.links.add(Pair.of(ids[i], ids[i + 1])); + } } public Id sourceLabel() { - return this.sourceLabel; + if (links.size() == 1) { + return links.iterator().next().getLeft(); + } + return NONE_ID; } public void sourceLabel(Id id) { - E.checkArgument(this.sourceLabel == NONE_ID, - "Not allowed to set source label multi times " + - "of edge label '%s'", this.name()); - this.sourceLabel = id; + E.checkArgument(this.links.isEmpty(), + "Not allowed add source label to an edge label which " + + "already has links"); + if (this.targetLabel != NONE_ID) { + this.links.add(Pair.of(id, this.targetLabel)); + this.targetLabel = NONE_ID; + } else { + this.sourceLabel = id; + } } public String targetLabelName() { - return this.graph.vertexLabelOrNone(this.targetLabel).name(); + E.checkState(this.links.size() == 1, + "Only edge label has single vertex label pair can call " + + "sourceLabelName(), but current edge label got %s", + this.links.size()); + return this.graph.vertexLabelOrNone(this.links.iterator().next().getRight()).name(); } public Id targetLabel() { - return this.targetLabel; + if (links.size() == 1) { + return links.iterator().next().getRight(); + } + return NONE_ID; } public void targetLabel(Id id) { - E.checkArgument(this.targetLabel == NONE_ID, - "Not allowed to set target label multi times " + - "of edge label '%s'", this.name()); - this.targetLabel = id; + E.checkArgument(this.links.isEmpty(), + "Not allowed add source label to an edge label which " + + "already has links"); + if (this.sourceLabel != NONE_ID) { + this.links.add(Pair.of(this.sourceLabel, id)); + this.sourceLabel = NONE_ID; + } else { + this.targetLabel = id; + } } public boolean linkWithLabel(Id id) { - return this.sourceLabel.equals(id) || this.targetLabel.equals(id); + for (Pair link : this.links) { + if (link.getLeft().equals(id) || link.getRight().equals(id)) { + return true; + } + } + return false; } public boolean linkWithVertexLabel(Id label, Directions dir) { - if (dir.equals(Directions.IN)) { - return this.targetLabel.equals(label); - } else if (dir.equals(Directions.OUT)) { - return this.sourceLabel.equals(label); - } else if (dir.equals(Directions.BOTH)) { - return this.targetLabel.equals(label) || this.sourceLabel.equals(label); - } - return false; + return this.links.stream().anyMatch(pair -> { + Id sourceLabel = pair.getLeft(); + Id targetLabel = pair.getRight(); + if (dir.equals(Directions.IN)) { + return targetLabel.equals(label); + } else if (dir.equals(Directions.OUT)) { + return sourceLabel.equals(label); + } else if (dir.equals(Directions.BOTH)) { + return targetLabel.equals(label) || sourceLabel.equals(label); + } + return false; + }); } public boolean checkLinkEqual(Id sourceLabel, Id targetLabel) { - return this.sourceLabel.equals(sourceLabel) && - this.targetLabel.equals(targetLabel); + return this.links.contains(Pair.of(sourceLabel, targetLabel)); + } + + public Set> links() { + return this.links; + } + + public void links(Pair link) { + if (this.links == null) { + this.links = new HashSet<>(); + } + this.links.add(link); } public boolean existSortKeys() { @@ -160,10 +244,16 @@ public interface Builder extends SchemaBuilder { Id rebuildIndex(); + Builder asBase(); + + Builder withBase(String fatherLabel); + Builder link(String sourceLabel, String targetLabel); + @Deprecated Builder sourceLabel(String label); + @Deprecated Builder targetLabel(String label); Builder singleTime(); @@ -221,13 +311,13 @@ public Map asMap() { map.put(P.SORT_KEYS, this.sortKeys); } - //map.put(P.EDGELABEL_TYPE, this.edgeLabelType); - //if (this.fatherId() != null) { - // map.put(P.FATHER_ID, this.fatherId().asString()); - //} + map.put(P.EDGELABEL_TYPE, this.edgeLabelType); + if (this.fatherId() != null) { + map.put(P.FATHER_ID, this.fatherId().asString()); + } map.put(P.ENABLE_LABEL_INDEX, this.enableLabelIndex()); map.put(P.TTL, String.valueOf(this.ttl())); - //map.put(P.LINKS, this.links()); + map.put(P.LINKS, this.links()); map.put(P.FREQUENCY, this.frequency().toString()); return super.asMap(map); @@ -278,17 +368,17 @@ public static EdgeLabel fromMap(Map map, HugeGraph graph) { Long.parseLong((String) entry.getValue()); edgeLabel.ttlStartTime(IdGenerator.of(ttlStartTime)); break; - //case P.LINKS: - // // TODO: serialize and deserialize - // List list = (List) entry.getValue(); - // for (Map m : list) { - // for (Object key : m.keySet()) { - // Id sid = IdGenerator.of(Long.parseLong((String) key)); - // Id tid = IdGenerator.of(Long.parseLong(String.valueOf(m.get(key)))); - // edgeLabel.links(Pair.of(sid, tid)); - // } - // } - // break; + case P.LINKS: + // TODO: serialize and deserialize + List list = (List) entry.getValue(); + for (Map m : list) { + for (Object key : m.keySet()) { + Id sid = IdGenerator.of(Long.parseLong((String) key)); + Id tid = IdGenerator.of(Long.parseLong(String.valueOf(m.get(key)))); + edgeLabel.links(Pair.of(sid, tid)); + } + } + break; case P.SOURCE_LABEL: long sourceLabel = Long.parseLong((String) entry.getValue()); @@ -299,17 +389,17 @@ public static EdgeLabel fromMap(Map map, HugeGraph graph) { Long.parseLong((String) entry.getValue()); edgeLabel.targetLabel(IdGenerator.of(targetLabel)); break; - //case P.FATHER_ID: - // long fatherId = - // Long.parseLong((String) entry.getValue()); - // edgeLabel.fatherId(IdGenerator.of(fatherId)); - // break; - //case P.EDGELABEL_TYPE: - // EdgeLabelType edgeLabelType = - // EdgeLabelType.valueOf( - // ((String) entry.getValue()).toUpperCase()); - // edgeLabel.edgeLabelType(edgeLabelType); - // break; + case P.FATHER_ID: + long fatherId = + Long.parseLong((String) entry.getValue()); + edgeLabel.fatherId(IdGenerator.of(fatherId)); + break; + case P.EDGELABEL_TYPE: + EdgeLabelType edgeLabelType = + EdgeLabelType.valueOf( + ((String) entry.getValue()).toUpperCase()); + edgeLabel.edgeLabelType(edgeLabelType); + break; case P.FREQUENCY: Frequency frequency = Frequency.valueOf(((String) entry.getValue()).toUpperCase()); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java index f7aa460e1e..410b094fb9 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java @@ -26,11 +26,11 @@ import java.util.Set; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.tuple.Pair; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.backend.id.Id; import org.apache.hugegraph.backend.id.IdGenerator; import org.apache.hugegraph.backend.tx.ISchemaTransaction; -import org.apache.hugegraph.backend.tx.SchemaTransaction; import org.apache.hugegraph.exception.ExistedException; import org.apache.hugegraph.exception.NotAllowException; import org.apache.hugegraph.exception.NotFoundException; @@ -40,6 +40,7 @@ import org.apache.hugegraph.schema.VertexLabel; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Action; +import org.apache.hugegraph.type.define.EdgeLabelType; import org.apache.hugegraph.type.define.Frequency; import org.apache.hugegraph.util.CollectionUtil; import org.apache.hugegraph.util.E; @@ -51,6 +52,9 @@ public class EdgeLabelBuilder extends AbstractBuilder private Id id; private String name; + private Set> links; + private EdgeLabelType edgeLabelType; + private String fatherLabel; private String sourceLabel; private String targetLabel; private Frequency frequency; @@ -69,8 +73,9 @@ public EdgeLabelBuilder(ISchemaTransaction transaction, E.checkNotNull(name, "name"); this.id = null; this.name = name; - this.sourceLabel = null; - this.targetLabel = null; + this.links = new HashSet<>(); + this.edgeLabelType = EdgeLabelType.NORMAL; + this.fatherLabel = null; this.frequency = Frequency.DEFAULT; this.properties = new HashSet<>(); this.sortKeys = new ArrayList<>(); @@ -89,8 +94,11 @@ public EdgeLabelBuilder(ISchemaTransaction transaction, HugeGraph origin = copy.graph(); this.id = null; this.name = copy.name(); - this.sourceLabel = copy.sourceLabelName(); - this.targetLabel = copy.targetLabelName(); + this.links = mapPairId2Name(origin, copy.links()); + this.edgeLabelType = copy.edgeLabelType(); + if (copy.edgeLabelType().sub()) { + this.fatherLabel = mapElId2Name(origin, copy.fatherId()); + } this.frequency = copy.frequency(); this.properties = mapPkId2Name(origin, copy.properties()); this.sortKeys = mapPkId2Name(origin, copy.sortKeys()); @@ -108,8 +116,10 @@ public EdgeLabel build() { this.id, this.name); HugeGraph graph = this.graph(); EdgeLabel edgeLabel = new EdgeLabel(graph, id, this.name); - edgeLabel.sourceLabel(graph.vertexLabel(this.sourceLabel).id()); - edgeLabel.targetLabel(graph.vertexLabel(this.targetLabel).id()); + for (Pair link : this.links) { + edgeLabel.links(Pair.of(graph.vertexLabel(link.getLeft()).id(), + graph.vertexLabel(link.getRight()).id())); + } edgeLabel.frequency(this.frequency == Frequency.DEFAULT ? Frequency.SINGLE : this.frequency); edgeLabel.ttl(this.ttl); @@ -132,9 +142,52 @@ public EdgeLabel build() { edgeLabel.nullableKey(propertyKey.id()); } edgeLabel.userdata(this.userdata); + if (this.edgeLabelType.sub()) { + edgeLabel.edgeLabelType(EdgeLabelType.SUB); + EdgeLabel fatherEl = graph.edgeLabel(this.fatherLabel); + edgeLabel.fatherId(fatherEl.id()); + registerInfoToFatherEl(fatherEl, edgeLabel); + } else { + edgeLabel.edgeLabelType(this.edgeLabelType); + } return edgeLabel; } + private void registerInfoToFatherEl(EdgeLabel fatherEl, EdgeLabel subEl) { + HugeGraph graph = this.graph(); + // When the new edge label is a subtype, register the links information + // of the sub edgelabel to the parent edge Label + for (Pair link : this.links) { + fatherEl.links(Pair.of(this.graph().vertexLabel(link.getLeft()).id(), + graph.vertexLabel(link.getRight()).id())); + } + + List fatherSortKeys = fatherEl.sortKeys(); + List subSortKeys = subEl.sortKeys(); + if (fatherSortKeys == null || fatherSortKeys.size() == 0) { + for (Id sortKey : subSortKeys) { + fatherEl.sortKeys(sortKey); + } + } else { + E.checkArgument(fatherSortKeys.size() == subSortKeys.size(), + "The sortKeys of each sub edgelabel need to be " + + "consistent. " + "Currently, the sortKeys of already exist edgelabel " + + "are " + "'%s', " + "and the sortKeys of newly added " + + "sub edgelabel are '%s'", + fatherSortKeys, subSortKeys); + for (int i = 0; i < fatherSortKeys.size(); i++) { + E.checkArgument(fatherSortKeys.get(i).equals(subSortKeys.get(i)), + "The sortKeys of each sub edgelabel need to be " + + "consistent. " + + "Currently, the sortKeys of already exist edgelabel " + + "are " + "'%s', " + "and the sortKeys of newly added " + + "sub edgelabel are '%s'", + fatherSortKeys, subSortKeys); + } + } + this.graph().updateEdgeLabel(fatherEl); + } + @Override public EdgeLabel create() { HugeType type = HugeType.EDGE_LABEL; @@ -177,14 +230,12 @@ public EdgeLabel create() { */ private boolean hasSameProperties(EdgeLabel existedEdgeLabel) { HugeGraph graph = this.graph(); - Id sourceId = graph.vertexLabel(this.sourceLabel).id(); - if (!existedEdgeLabel.sourceLabel().equals(sourceId)) { - return false; - } - - Id targetId = graph.vertexLabel(this.targetLabel).id(); - if (!existedEdgeLabel.targetLabel().equals(targetId)) { - return false; + for (Pair link : existedEdgeLabel.links()) { + String sourceName = graph.vertexLabel(link.getLeft()).name(); + String targetName = graph.vertexLabel(link.getRight()).name(); + if (!this.links.contains(Pair.of(sourceName, targetName))) { + return false; + } } if ((this.frequency == Frequency.DEFAULT && @@ -302,6 +353,28 @@ public Id rebuildIndex() { return this.graph().rebuildIndex(edgeLabel); } + @Override + public EdgeLabel.Builder asBase() { + this.edgeLabelType = EdgeLabelType.PARENT; + return this; + } + + @Override + public EdgeLabel.Builder withBase(String fatherLabel) { + // Check if fatherLabel is reasonable (if it exists or not) + E.checkArgumentNotNull(fatherLabel, "When creating a subtype edgeLabel, " + + "the edgeLabel name of the parent type edgeLabel must" + + " be entered"); + EdgeLabel edgeLabel = this.edgeLabelOrNull(fatherLabel); + if (edgeLabel == null) { + throw new NotFoundException("Can't create subtype edge label '%s' " + + "since it's parent edge label doesn't exist", this.name); + } + this.edgeLabelType = EdgeLabelType.SUB; + this.fatherLabel = fatherLabel; + return this; + } + @Override public EdgeLabelBuilder id(long id) { E.checkArgument(id != 0L, "Not allowed to assign 0 as edge label id"); @@ -340,20 +413,38 @@ public EdgeLabelBuilder sortKeys(String... keys) { @Override public EdgeLabelBuilder link(String sourceLabel, String targetLabel) { - this.sourceLabel(sourceLabel); - this.targetLabel(targetLabel); + if (this.links == null) { + this.links = new HashSet<>(); + } + this.links.add(Pair.of(sourceLabel, targetLabel)); return this; } @Override public EdgeLabelBuilder sourceLabel(String label) { - this.sourceLabel = label; + E.checkArgument(this.links.isEmpty(), + "Not allowed add source label to an edge label which " + + "already has links"); + if (this.targetLabel != null) { + this.links.add(Pair.of(label, this.targetLabel)); + this.targetLabel = null; + } else { + this.sourceLabel = label; + } return this; } @Override public EdgeLabelBuilder targetLabel(String label) { - this.targetLabel = label; + E.checkArgument(this.links.isEmpty(), + "Not allowed add source label to an edge label which " + + "already has links"); + if (this.sourceLabel != null) { + this.links.add(Pair.of(this.sourceLabel, label)); + this.sourceLabel = null; + } else { + this.targetLabel = label; + } return this; } @@ -518,19 +609,32 @@ private void checkSortKeys() { } private void checkRelation() { - String srcLabel = this.sourceLabel; - String tgtLabel = this.targetLabel; - - E.checkArgument(srcLabel != null && tgtLabel != null, - "Must set source and target label " + - "for edge label '%s'", this.name); - - E.checkArgumentNotNull(this.vertexLabelOrNull(srcLabel), - "Undefined source vertex label '%s' " + - "in edge label '%s'", srcLabel, this.name); - E.checkArgumentNotNull(this.vertexLabelOrNull(tgtLabel), - "Undefined target vertex label '%s' " + - "in edge label '%s'", tgtLabel, this.name); + if (this.edgeLabelType.parent()) { + E.checkArgument(this.links.isEmpty(), + "The links of the parent edge label must be empty"); + } else { + E.checkArgument(!this.links.isEmpty(), + "The links of standard and subtype edge label " + + "can't be empty"); + E.checkArgument(this.links.size() == 1, + "The links size of standard and subtype edge " + + "label must be 1"); + for (Pair link : this.links) { + String srcLabel = link.getLeft(); + String tgtLabel = link.getRight(); + E.checkArgument(srcLabel != null && tgtLabel != null, + "Must set source and target label " + + "for edge label '%s'", this.name); + E.checkArgumentNotNull(this.vertexLabelOrNull(srcLabel), + "Undefined source vertex label '%s' " + + "in edge label '%s'", srcLabel, + this.name); + E.checkArgumentNotNull(this.vertexLabelOrNull(tgtLabel), + "Undefined target vertex label '%s' " + + "in edge label '%s'", tgtLabel, + this.name); + } + } } private void checkStableVars() { @@ -544,6 +648,11 @@ private void checkStableVars() { "Not allowed to update target label " + "for edge label '%s', it must be null", this.name); } + if (this.links != null && !this.links.isEmpty()) { + throw new NotAllowException( + "Not allowed to update source/target label " + + "for edge label '%s', it must be null", this.name); + } if (this.frequency != Frequency.DEFAULT) { throw new NotAllowException( "Not allowed to update frequency " + @@ -569,15 +678,17 @@ private void checkTtl() { "Can't set ttl start time if ttl is not set"); return; } - VertexLabel source = this.graph().vertexLabel(this.sourceLabel); - VertexLabel target = this.graph().vertexLabel(this.targetLabel); - E.checkArgument((source.ttl() == 0L || this.ttl <= source.ttl()) && - (target.ttl() == 0L || this.ttl <= target.ttl()), - "The ttl(%s) of edge label '%s' should less than " + - "ttl(%s) of source label '%s' and ttl(%s) of target " + - "label '%s'", this.ttl, this.name, - source.ttl(), this.sourceLabel, - target.ttl(), this.targetLabel); + for (Pair link : this.links) { + VertexLabel source = this.graph().vertexLabel(link.getLeft()); + VertexLabel target = this.graph().vertexLabel(link.getRight()); + E.checkArgument((source.ttl() == 0L || this.ttl <= source.ttl()) && + (target.ttl() == 0L || this.ttl <= target.ttl()), + "The ttl(%s) of edge label '%s' should less than " + + "ttl(%s) of source label '%s' and ttl(%s) of target " + + "label '%s'", this.ttl, this.name, + source.ttl(), link.getLeft(), + target.ttl(), link.getRight()); + } if (this.ttlStartTime == null) { return; } @@ -624,4 +735,13 @@ private static Set mapPkId2Name(HugeGraph graph, Set ids) { private static List mapPkId2Name(HugeGraph graph, List ids) { return graph.mapPkId2Name(ids); } + + private static String mapElId2Name(HugeGraph graph, Id fatherId) { + return graph.mapElId2Name(ImmutableList.of(fatherId)).get(0); + } + + private static Set> mapPairId2Name(HugeGraph graph, + Set> pairs) { + return graph.mapPairId2Name(pairs); + } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java index 53b8a54933..5bf7011a6f 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java @@ -21,6 +21,7 @@ import java.util.Iterator; import java.util.List; +import org.apache.commons.lang3.tuple.Pair; import org.apache.hugegraph.HugeException; import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.backend.id.EdgeId; @@ -141,15 +142,24 @@ public boolean isDirection(Directions direction) { @Watched(prefix = "edge") public void assignId() { // Generate an id and assign - this.id = new EdgeId(this.ownerVertex(), this.direction(), - this.schemaLabel().id(), this.name(), - this.otherVertex()); + if (this.schemaLabel().hasFather()) { + this.id = new EdgeId(this.ownerVertex(), this.direction(), + this.schemaLabel().fatherId(), + this.schemaLabel().id(), + this.name(), + this.otherVertex()); + } else { + this.id = new EdgeId(this.ownerVertex(), this.direction(), + this.schemaLabel().id(), + this.schemaLabel().id(), + this.name(), this.otherVertex()); + } if (this.fresh()) { int len = this.id.length(); - E.checkArgument(len <= BytesBuffer.BIG_ID_LEN_MAX, + E.checkArgument(len <= BytesBuffer.EID_LEN_MAX, "The max length of edge id is %s, but got %s {%s}", - BytesBuffer.BIG_ID_LEN_MAX, len, this.id); + BytesBuffer.EID_LEN_MAX, len, this.id); } } @@ -315,9 +325,15 @@ public Object sysprop(HugeKeys key) { case OWNER_VERTEX: return this.ownerVertex().id(); case LABEL: - return this.schemaLabel().id(); + if (this.schemaLabel().hasFather()) { + return this.schemaLabel().fatherId(); + } else { + return this.schemaLabel().id(); + } case DIRECTION: return this.direction(); + case SUB_LABEL: + return this.schemaLabel().id(); case OTHER_VERTEX: return this.otherVertex().id(); case SORT_VALUES: @@ -363,11 +379,15 @@ public Vertex inVertex() { public void vertices(HugeVertex owner, HugeVertex other) { Id ownerLabel = owner.schemaLabel().id(); - if (ownerLabel.equals(this.label.sourceLabel())) { - this.vertices(true, owner, other); - } else { - assert ownerLabel.equals(this.label.targetLabel()); - this.vertices(false, owner, other); + Id otherLabel = other.schemaLabel().id(); + for (Pair link : this.label.links()) { + if (ownerLabel.equals(link.getLeft()) && + otherLabel.equals(link.getRight())) { + this.vertices(true, owner, other); + } else if (ownerLabel.equals(link.getRight()) && + otherLabel.equals(link.getLeft())) { + this.vertices(false, owner, other); + } } } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeElement.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeElement.java index 137e623d86..adb12f31bc 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeElement.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeElement.java @@ -55,7 +55,6 @@ public abstract class HugeElement implements Element, GraphType, Idfiable, Compa private static final MutableIntObjectMap> EMPTY_MAP = CollectionFactory.newIntObjectMap(); - private static final int MAX_PROPERTIES = BytesBuffer.UINT16_MAX; private final HugeGraph graph; private MutableIntObjectMap> properties; @@ -279,7 +278,7 @@ public HugeProperty setProperty(HugeProperty prop) { PropertyKey pkey = prop.propertyKey(); E.checkArgument(this.properties.containsKey(intFromId(pkey.id())) || - this.properties.size() < MAX_PROPERTIES, + this.properties.size() < BytesBuffer.MAX_PROPERTIES, "Exceeded the maximum number of properties"); return this.properties.put(intFromId(pkey.id()), prop); } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java index 4726e88e5b..389b0f0e8c 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java @@ -303,6 +303,8 @@ public HugeEdge constructEdge(String label, HugeVertex vertex, E.checkArgument(label != null && !label.isEmpty(), "Edge label can't be null or empty"); EdgeLabel edgeLabel = this.graph().edgeLabel(label); + E.checkArgument(!edgeLabel.isFather(), "Adding an edge of parent type " + + "is not allowed"); // Check link E.checkArgument(edgeLabel.checkLinkEqual(this.schemaLabel().id(), vertex.schemaLabel().id()), diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeServerInfo.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeServerInfo.java index a304b4f75b..71feb3f688 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeServerInfo.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeServerInfo.java @@ -20,7 +20,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -47,14 +46,13 @@ public class HugeServerInfo { // Unit millisecond - private static final long EXPIRED_INTERVAL = - TaskManager.SCHEDULE_PERIOD * 10; + private static final long EXPIRED_INTERVAL = TaskManager.SCHEDULE_PERIOD * 10; - private Id id; private NodeRole role; + private Date updateTime; private int maxLoad; private int load; - private Date updateTime; + private final Id id; private transient boolean updated = false; @@ -114,6 +112,10 @@ public void increaseLoad(int delta) { this.updated = true; } + public long expireTime() { + return this.updateTime.getTime() + EXPIRED_INTERVAL; + } + public Date updateTime() { return this.updateTime; } @@ -200,8 +202,7 @@ public Map asMap() { public static HugeServerInfo fromVertex(Vertex vertex) { HugeServerInfo serverInfo = new HugeServerInfo((Id) vertex.id()); - for (Iterator> iter = vertex.properties(); - iter.hasNext(); ) { + for (var iter = vertex.properties(); iter.hasNext(); ) { VertexProperty prop = iter.next(); serverInfo.property(prop.key(), prop.value()); } @@ -246,7 +247,7 @@ public static final class Schema { public static final String SERVER = P.SERVER; - protected final HugeGraphParams graph; + private final HugeGraphParams graph; public Schema(HugeGraphParams graph) { this.graph = graph; @@ -264,8 +265,7 @@ public void initSchemaIfNeeded() { VertexLabel label = graph.schema().vertexLabel(SERVER) .properties(properties) .useCustomizeStringId() - .nullableKeys(P.ROLE, P.MAX_LOAD, - P.LOAD, P.UPDATE_TIME) + .nullableKeys(P.ROLE, P.MAX_LOAD, P.LOAD, P.UPDATE_TIME) .enableLabelIndex(true) .build(); this.graph.schemaTransaction().addVertexLabel(label); @@ -273,7 +273,6 @@ public void initSchemaIfNeeded() { private String[] initProperties() { List props = new ArrayList<>(); - props.add(createPropertyKey(P.ROLE, DataType.BYTE)); props.add(createPropertyKey(P.MAX_LOAD, DataType.INT)); props.add(createPropertyKey(P.LOAD, DataType.INT)); @@ -283,8 +282,7 @@ private String[] initProperties() { } public boolean existVertexLabel(String label) { - return this.graph.schemaTransaction() - .getVertexLabel(label) != null; + return this.graph.schemaTransaction().getVertexLabel(label) != null; } @SuppressWarnings("unused") @@ -296,8 +294,7 @@ private String createPropertyKey(String name, DataType dataType) { return this.createPropertyKey(name, dataType, Cardinality.SINGLE); } - private String createPropertyKey(String name, DataType dataType, - Cardinality cardinality) { + private String createPropertyKey(String name, DataType dataType, Cardinality cardinality) { SchemaManager schema = this.graph.graph().schema(); PropertyKey propertyKey = schema.propertyKey(name) .dataType(dataType) diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTask.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTask.java index c07b9e8d47..f9e4f120f4 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTask.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/HugeTask.java @@ -725,7 +725,7 @@ private void checkPropertySize(String property, String propertyName) { } private void checkPropertySize(int propertyLength, String propertyName) { - long propertyLimit = BytesBuffer.STRING_LEN_MAX; + long propertyLimit = BytesBuffer.MAX_PROPERTIES; HugeGraph graph = this.scheduler().graph(); if (propertyName.equals(P.INPUT)) { propertyLimit = graph.option(CoreOptions.TASK_INPUT_SIZE_LIMIT); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/ServerInfoManager.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/ServerInfoManager.java index de0d08b03a..bcef869017 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/ServerInfoManager.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/ServerInfoManager.java @@ -67,8 +67,7 @@ public class ServerInfoManager { private volatile boolean onlySingleNode; private volatile boolean closed; - public ServerInfoManager(HugeGraphParams graph, - ExecutorService dbExecutor) { + public ServerInfoManager(HugeGraphParams graph, ExecutorService dbExecutor) { E.checkNotNull(graph, "graph"); E.checkNotNull(dbExecutor, "db executor"); @@ -107,9 +106,20 @@ public synchronized void initServerInfo(GlobalMasterInfo nodeInfo) { Id serverId = nodeInfo.nodeId(); HugeServerInfo existed = this.serverInfo(serverId); + if (existed != null && existed.alive()) { + final long now = DateUtil.now().getTime(); + if (existed.expireTime() > now + 30 * 1000) { + LOG.info("The node time maybe skew very much: {}", existed); + throw new HugeException("The server with name '%s' maybe skew very much", serverId); + } + try { + Thread.sleep(existed.expireTime() - now + 1); + } catch (InterruptedException e) { + throw new HugeException("Interrupted when waiting for server info expired", e); + } + } E.checkArgument(existed == null || !existed.alive(), - "The server with name '%s' already in cluster", - serverId); + "The server with name '%s' already in cluster", serverId); if (nodeInfo.nodeRole().master()) { String page = this.supportsPaging() ? PageInfo.PAGE_NONE : null; @@ -185,13 +195,12 @@ public synchronized void heartbeat() { /* ServerInfo is missing */ if (this.selfNodeId() == null) { // Ignore if ServerInfo is not initialized - LOG.info("ServerInfo is missing: {}, may not be initialized yet"); + LOG.info("ServerInfo is missing: {}, may not be initialized yet", this.selfNodeId()); return; } if (this.selfIsMaster()) { - // On master node, just wait for ServerInfo re-init - LOG.warn("ServerInfo is missing: {}, may be cleared before", - this.selfNodeId()); + // On the master node, just wait for ServerInfo re-init + LOG.warn("ServerInfo is missing: {}, may be cleared before", this.selfNodeId()); return; } /* @@ -232,12 +241,10 @@ protected synchronized HugeServerInfo pickWorkerNode(Collection if (!server.alive()) { continue; } - if (server.role().master()) { master = server; continue; } - hasWorkerNode = true; if (!server.suitableFor(task, now)) { continue; @@ -254,13 +261,12 @@ protected synchronized HugeServerInfo pickWorkerNode(Collection this.onlySingleNode = singleNode; } - // Only schedule to master if there is no workers and master is suitable + // Only schedule to master if there are no workers and master are suitable if (!hasWorkerNode) { if (master != null && master.suitableFor(task, now)) { serverWithMinLoad = master; } } - return serverWithMinLoad; } @@ -286,8 +292,7 @@ private Id save(HugeServerInfo serverInfo) { throw new HugeException("Schema is missing for %s '%s'", HugeServerInfo.P.SERVER, serverInfo); } - HugeVertex vertex = this.tx().constructVertex(false, - serverInfo.asArray()); + HugeVertex vertex = this.tx().constructVertex(false, serverInfo.asArray()); // Add or update server info in backend store vertex = this.tx().addVertex(vertex); return vertex.id(); @@ -301,8 +306,7 @@ private int save(Collection serverInfos) { } HugeServerInfo.Schema schema = HugeServerInfo.schema(this.graph); if (!schema.existVertexLabel(HugeServerInfo.P.SERVER)) { - throw new HugeException("Schema is missing for %s", - HugeServerInfo.P.SERVER); + throw new HugeException("Schema is missing for %s", HugeServerInfo.P.SERVER); } // Save server info in batch GraphTransaction tx = this.tx(); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/StandardTaskScheduler.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/StandardTaskScheduler.java index 8afe11dff2..1395888611 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/StandardTaskScheduler.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/task/StandardTaskScheduler.java @@ -120,7 +120,7 @@ private TaskTransaction tx() { if (this.taskTx == null) { BackendStore store = this.graph.loadSystemStore(); TaskTransaction tx = new TaskTransaction(this.graph, store); - assert this.taskTx == null; // may be reentrant? + assert this.taskTx == null; // maybe reentrant? this.taskTx = tx; } } @@ -196,7 +196,7 @@ public Future schedule(HugeTask task) { if (this.serverManager().onlySingleNode() && !task.computer()) { /* - * Speed up for single node, submit task immediately, + * Speed up for single node, submit the task immediately, * this code can be removed without affecting code logic */ task.status(TaskStatus.QUEUED); @@ -205,7 +205,7 @@ public Future schedule(HugeTask task) { return this.submitTask(task); } else { /* - * Just set SCHEDULING status and save task, + * Just set the SCHEDULING status and save the task, * it will be scheduled by periodic scheduler worker */ task.status(TaskStatus.SCHEDULING); @@ -276,11 +276,11 @@ public synchronized void cancel(HugeTask task) { assert this.serverManager().selfIsMaster(); if (!task.server().equals(this.serverManager().selfNodeId())) { /* - * Remove task from memory if it's running on worker node, - * but keep task in memory if it's running on master node. - * cancel-scheduling will read task from backend store, if + * Remove the task from memory if it's running on worker node, + * but keep the task in memory if it's running on master node. + * Cancel-scheduling will read the task from backend store, if * removed this instance from memory, there will be two task - * instances with same id, and can't cancel the real task that + * instances with the same id, and can't cancel the real task that * is running but removed from memory. */ this.remove(task); @@ -301,12 +301,10 @@ public ServerInfoManager serverManager() { protected synchronized void scheduleTasksOnMaster() { // Master server schedule all scheduling tasks to suitable worker nodes - Collection serverInfos = this.serverManager() - .allServerInfos(); + Collection serverInfos = this.serverManager().allServerInfos(); String page = this.supportsPaging() ? PageInfo.PAGE_NONE : null; do { - Iterator> tasks = this.tasks(TaskStatus.SCHEDULING, - PAGE_SIZE, page); + Iterator> tasks = this.tasks(TaskStatus.SCHEDULING, PAGE_SIZE, page); while (tasks.hasNext()) { HugeTask task = tasks.next(); if (task.server() != null) { @@ -318,12 +316,10 @@ protected synchronized void scheduleTasksOnMaster() { return; } - HugeServerInfo server = this.serverManager().pickWorkerNode( - serverInfos, task); + HugeServerInfo server = this.serverManager().pickWorkerNode(serverInfos, task); if (server == null) { LOG.info("The master can't find suitable servers to " + - "execute task '{}', wait for next schedule", - task.id()); + "execute task '{}', wait for next schedule", task.id()); continue; } @@ -336,8 +332,7 @@ protected synchronized void scheduleTasksOnMaster() { // Update server load in memory, it will be saved at the ending server.increaseLoad(task.load()); - LOG.info("Scheduled task '{}' to server '{}'", - task.id(), server.id()); + LOG.info("Scheduled task '{}' to server '{}'", task.id(), server.id()); } if (page != null) { page = PageInfo.pageInfo(tasks); @@ -351,8 +346,7 @@ protected synchronized void scheduleTasksOnMaster() { protected void executeTasksOnWorker(Id server) { String page = this.supportsPaging() ? PageInfo.PAGE_NONE : null; do { - Iterator> tasks = this.tasks(TaskStatus.SCHEDULED, - PAGE_SIZE, page); + Iterator> tasks = this.tasks(TaskStatus.SCHEDULED, PAGE_SIZE, page); while (tasks.hasNext()) { HugeTask task = tasks.next(); this.initTaskCallable(task); @@ -381,8 +375,7 @@ protected void executeTasksOnWorker(Id server) { protected void cancelTasksOnWorker(Id server) { String page = this.supportsPaging() ? PageInfo.PAGE_NONE : null; do { - Iterator> tasks = this.tasks(TaskStatus.CANCELLING, - PAGE_SIZE, page); + Iterator> tasks = this.tasks(TaskStatus.CANCELLING, PAGE_SIZE, page); while (tasks.hasNext()) { HugeTask task = tasks.next(); Id taskServer = task.server(); @@ -557,10 +550,10 @@ public HugeTask delete(Id id, boolean force) { HugeTask task = this.task(id); /* - * The following is out of date when task running on worker node: + * The following is out of date when the task running on worker node: * HugeTask task = this.tasks.get(id); * Tasks are removed from memory after completed at most time, - * but there is a tiny gap between tasks are completed and + * but there is a tiny gap between tasks is completed and * removed from memory. * We assume tasks only in memory may be incomplete status, * in fact, it is also possible to appear on the backend tasks @@ -621,7 +614,7 @@ private HugeTask waitUntilTaskCompleted(Id id, long seconds, throw e; } if (task.completed()) { - // Wait for task result being set after status is completed + // Wait for the task result being set after the status is completed sleep(intervalMs); return task; } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/HugeTraverser.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/HugeTraverser.java index 57c7c0a31d..8122c79080 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/HugeTraverser.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/HugeTraverser.java @@ -479,7 +479,7 @@ public EdgesIterator edgesOfVertices(Iterator sources, public Iterator edgesOfVertex(Id source, Steps steps) { List edgeLabels = steps.edgeLabels(); ConditionQuery cq = GraphTransaction.constructEdgesQuery( - source, steps.direction(), edgeLabels); + source, steps.direction(), edgeLabels.toArray(new Id[0])); cq.capacity(Query.NO_CAPACITY); if (steps.limit() != NO_LIMIT) { cq.limit(steps.limit()); diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStep.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStep.java index c35305e2b8..bd2e1388c8 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStep.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeVertexStep.java @@ -29,6 +29,7 @@ import org.apache.hugegraph.backend.query.Query; import org.apache.hugegraph.backend.query.QueryResults; import org.apache.hugegraph.backend.tx.GraphTransaction; +import org.apache.hugegraph.schema.EdgeLabel; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.util.Log; import org.apache.tinkerpop.gremlin.process.traversal.Traverser; @@ -132,16 +133,15 @@ protected ConditionQuery constructEdgesQuery( Id vertex = (Id) traverser.get().id(); Directions direction = Directions.convert(this.getDirection()); - Id[] edgeLabels = graph.mapElName2Id(this.getEdgeLabels()); + EdgeLabel[] els = graph.mapElName2El(this.getEdgeLabels()); LOG.debug("HugeVertexStep.edges(): vertex={}, direction={}, " + "edgeLabels={}, has={}", - vertex, direction, edgeLabels, this.hasContainers); + vertex, direction, els, this.hasContainers); - ConditionQuery query = GraphTransaction.constructEdgesQuery( - vertex, direction, edgeLabels); + ConditionQuery query = GraphTransaction.constructEdgesQuery(vertex, direction, els); // Query by sort-keys - if (withEdgeCond && edgeLabels.length == 1) { + if (withEdgeCond && els.length == 1) { TraversalUtil.fillConditionQuery(query, this.hasContainers, graph); if (!GraphTransaction.matchPartialEdgeSortKeys(query, graph)) { // Can't query by sysprop and by index (HugeGraph-749) diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/EdgeLabelType.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/EdgeLabelType.java index 912ed43d55..2857c6e3b3 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/EdgeLabelType.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/EdgeLabelType.java @@ -19,14 +19,11 @@ public enum EdgeLabelType implements SerialEnum { - NORMAL(1, "NORMAL"), PARENT(2, "PARENT"), SUB(3, "SUB"), - - GENERAL(4, "GENERAL"), ; static { @@ -62,9 +59,4 @@ public boolean parent() { public boolean sub() { return this == SUB; } - - public boolean general() { - return this == GENERAL; - } - } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java index 5ffa3997ff..0e3536b011 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/HugeKeys.java @@ -48,6 +48,8 @@ public enum HugeKeys { SORT_KEYS(84, "sort_keys"), TTL(85, "ttl"), TTL_START_TIME(86, "ttl_start_time"), + EDGELABEL_TYPE(87, "edgelabel_type"), + PARENT_LABEL(89, "parent_label"), /* Column names of schema type (PropertyKey) */ DATA_TYPE(120, "data_type"), @@ -77,6 +79,7 @@ public enum HugeKeys { SORT_VALUES(206, "sort_values"), PRIMARY_VALUES(207, "primary_values"), EXPIRED_TIME(208, "expired_time"), + SUB_LABEL(211, "sub_label"), PROPERTY_TYPE(249, "property_type"), AGGREGATE_PROPERTIES(250, "aggregate_properties"); diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/hugegraph-server.sh b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/hugegraph-server.sh index 8b6a16d5ad..857b9b5356 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/hugegraph-server.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/hugegraph-server.sh @@ -121,9 +121,9 @@ fi # Using G1GC as the default garbage collector (Recommended for large memory machines) # mention: zgc is only available on ARM-Mac with java > 13 case "$GC_OPTION" in - g1|G1|g1gc) + "") echo "Using G1GC as the default garbage collector" - JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+UseG1GC -XX:+ParallelRefProcEnabled \ + JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+ParallelRefProcEnabled \ -XX:InitiatingHeapOccupancyPercent=50 \ -XX:G1RSetUpdatingPauseTimePercent=5" ;; @@ -134,9 +134,8 @@ case "$GC_OPTION" in -XX:ZCollectionInterval=120 -XX:ZAllocationSpikeTolerance=5 \ -XX:+UnlockDiagnosticVMOptions -XX:-ZProactive" ;; - "") ;; *) - echo "Unrecognized gc option: '$GC_OPTION', only support 'G1/ZGC' now" >> ${OUTPUT} + echo "Unrecognized gc option: '$GC_OPTION', default use g1, options only support 'ZGC' now" >> ${OUTPUT} exit 1 esac diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hstore.properties.template b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hstore.properties.template new file mode 100644 index 0000000000..3e90c5f4b7 --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hstore.properties.template @@ -0,0 +1,90 @@ +# gremlin entrance to create graph +# auth config: org.apache.hugegraph.auth.HugeFactoryAuthProxy +gremlin.graph=org.apache.hugegraph.HugeFactory + +# cache config +#schema.cache_capacity=100000 +# vertex-cache default is 1000w, 10min expired +vertex.cache_type=l2 +#vertex.cache_capacity=10000000 +#vertex.cache_expire=600 +# edge-cache default is 100w, 10min expired +edge.cache_type=l2 +#edge.cache_capacity=1000000 +#edge.cache_expire=600 + + +# schema illegal name template +#schema.illegal_name_regex=\s+|~.* + +#vertex.default_label=vertex + +backend=hstore +serializer=binary + +store=hugegraph + +# pd config +pd.peers=127.0.0.1:8686 + +# task config +task.scheduler_type=local +task.schedule_period=10 +task.retry=0 +task.wait_timeout=10 + +# search config +search.text_analyzer=jieba +search.text_analyzer_mode=INDEX + +# rocksdb backend config +#rocksdb.data_path=/path/to/disk +#rocksdb.wal_path=/path/to/disk + + +# cassandra backend config +cassandra.host=localhost +cassandra.port=9042 +cassandra.username= +cassandra.password= +#cassandra.connect_timeout=5 +#cassandra.read_timeout=20 +#cassandra.keyspace.strategy=SimpleStrategy +#cassandra.keyspace.replication=3 + +# hbase backend config +#hbase.hosts=localhost +#hbase.port=2181 +#hbase.znode_parent=/hbase +#hbase.threads_max=64 +# IMPORTANT: recommend to modify the HBase partition number +# by the actual/env data amount & RS amount before init store +# It will influence the load speed a lot +#hbase.enable_partition=true +#hbase.vertex_partitions=10 +#hbase.edge_partitions=30 + +# mysql backend config +#jdbc.driver=com.mysql.jdbc.Driver +#jdbc.url=jdbc:mysql://127.0.0.1:3306 +#jdbc.username=root +#jdbc.password= +#jdbc.reconnect_max_times=3 +#jdbc.reconnect_interval=3 +#jdbc.ssl_mode=false + +# postgresql & cockroachdb backend config +#jdbc.driver=org.postgresql.Driver +#jdbc.url=jdbc:postgresql://localhost:5432/ +#jdbc.username=postgres +#jdbc.password= +#jdbc.postgresql.connect_database=template1 + +# palo backend config +#palo.host=127.0.0.1 +#palo.poll_interval=10 +#palo.temp_dir=./palo-data +#palo.file_limit_size=32 + +# WARNING: These raft configurations are deprecated, please use the latest version instead. +# raft.mode=false diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hugegraph.properties b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hugegraph.properties index 1a3532914b..52c81bef1d 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hugegraph.properties +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hugegraph.properties @@ -19,13 +19,13 @@ edge.cache_type=l2 #vertex.default_label=vertex -backend=hstore +backend=rocksdb serializer=binary store=hugegraph # pd config -pd.peers=127.0.0.1:8686 +#pd.peers=127.0.0.1:8686 # task config task.scheduler_type=local @@ -33,28 +33,6 @@ task.schedule_period=10 task.retry=0 task.wait_timeout=10 -# raft config -raft.mode=false -raft.path=./raft-log -raft.safe_read=true -raft.use_replicator_pipeline=true -raft.election_timeout=10000 -raft.snapshot_interval=3600 -raft.backend_threads=48 -raft.read_index_threads=8 -raft.snapshot_threads=4 -raft.snapshot_parallel_compress=false -raft.snapshot_compress_threads=4 -raft.snapshot_decompress_threads=4 -raft.read_strategy=ReadOnlyLeaseBased -raft.queue_size=16384 -raft.queue_publish_timeout=60 -raft.apply_batch=1 -raft.rpc_threads=80 -raft.rpc_connect_timeout=5000 -raft.rpc_timeout=60 -raft.install_snapshot_rpc_timeout=36000 - # search config search.text_analyzer=jieba search.text_analyzer_mode=INDEX @@ -107,3 +85,6 @@ cassandra.password= #palo.poll_interval=10 #palo.temp_dir=./palo-data #palo.file_limit_size=32 + +# WARNING: These raft configurations are deprecated, please use the latest version instead. +# raft.mode=false diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties index 507867380c..9d6bb2ca82 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties @@ -1,6 +1,7 @@ # bind url # could use '0.0.0.0' or specified (real)IP to expose external network access restserver.url=http://127.0.0.1:8080 +#restserver.enable_graphspaces_filter=false # gremlin server url, need to be consistent with host and port in gremlin-server.yaml #gremlinserver.url=http://127.0.0.1:8182 @@ -52,3 +53,7 @@ server.role=master # slow query log log.slow_query_threshold=1000 + +# jvm(in-heap) memory usage monitor, set 1 to disable it +memory_monitor.threshold=0.85 +memory_monitor.period=2000 diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft1/graphs/hugegraph.properties b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft1/graphs/hugegraph.properties index 2d315b21e8..6b04fffb75 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft1/graphs/hugegraph.properties +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft1/graphs/hugegraph.properties @@ -26,6 +26,5 @@ serializer=binary rocksdb.data_path=rocksdb-data-raft1 rocksdb.wal_path=rocksdb-data-raft1 -raft.mode=true -raft.path=rocksdb-raftlog1 -raft.safe_read=true +# WARNING: These raft configurations are deprecated, please use the latest version instead. +# raft.mode=false diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft2/graphs/hugegraph.properties b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft2/graphs/hugegraph.properties index 772d387ad6..b04c8a494e 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft2/graphs/hugegraph.properties +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft2/graphs/hugegraph.properties @@ -26,6 +26,5 @@ serializer=binary rocksdb.data_path=rocksdb-data-raft2 rocksdb.wal_path=rocksdb-data-raft2 -raft.mode=true -raft.path=rocksdb-raftlog2 -raft.safe_read=true +# WARNING: These raft configurations are deprecated, please use the latest version instead. +# raft.mode=false diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft3/graphs/hugegraph.properties b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft3/graphs/hugegraph.properties index fc805c3c57..f7dc3f2711 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft3/graphs/hugegraph.properties +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/conf-raft3/graphs/hugegraph.properties @@ -26,6 +26,5 @@ serializer=binary rocksdb.data_path=rocksdb-data-raft3 rocksdb.wal_path=rocksdb-data-raft3 -raft.mode=true -raft.path=rocksdb-raftlog3 -raft.safe_read=true +# WARNING: These raft configurations are deprecated, please use the latest version instead. +# raft.mode=false diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test-for-raft.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test-for-raft.sh index 529874f58b..2b998d57aa 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test-for-raft.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test-for-raft.sh @@ -35,7 +35,7 @@ JACOCO_PORT=36320 RAFT_TOOLS=$RAFT1_DIR/bin/raft-tools.sh RAFT_LEADER="127.0.0.1:8091" -mvn package -DskipTests +mvn package -Dmaven.test.skip=true # mkdir for each raft-server cp -r $SERVER_DIR $RAFT1_DIR diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh index 8008f39cdb..2a3c2c35ee 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh @@ -29,7 +29,7 @@ REST_SERVER_CONF=$SERVER_DIR/conf/rest-server.properties GREMLIN_SERVER_CONF=$SERVER_DIR/conf/gremlin-server.yaml JACOCO_PORT=36320 -mvn package -DskipTests -ntp +mvn package -Dmaven.test.skip=true -ntp # add mysql dependency wget -P $SERVER_DIR/lib/ https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar @@ -41,6 +41,7 @@ fi # config rest-server sed -i 's/#auth.authenticator=/auth.authenticator=org.apache.hugegraph.auth.StandardAuthenticator/' $REST_SERVER_CONF sed -i 's/#auth.admin_token=/auth.admin_token=pa/' $REST_SERVER_CONF +sed -i 's/#restserver.enable_graphspaces_filter=false/restserver.enable_graphspaces_filter=true/' $REST_SERVER_CONF # config hugegraph.properties sed -i 's/gremlin.graph=.*/gremlin.graph=org.apache.hugegraph.auth.HugeFactoryAuthProxy/' $CONF diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/cmd/InitStore.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/cmd/InitStore.java index 255528932e..e3053a2096 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/cmd/InitStore.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/cmd/InitStore.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Objects; import org.apache.commons.collections.map.MultiValueMap; import org.apache.hugegraph.HugeFactory; @@ -77,7 +78,13 @@ public static void main(String[] args) throws Exception { List graphs = new ArrayList<>(graph2ConfigPaths.size()); try { for (Map.Entry entry : graph2ConfigPaths.entrySet()) { - graphs.add(initGraph(entry.getValue())); + String configPath = entry.getValue(); + HugeConfig config = new HugeConfig(configPath); + if (Objects.equals(config.get(CoreOptions.BACKEND), "hstore")) { + // skip initializing hstore backend + continue; + } + graphs.add(initGraph(configPath)); } StandardAuthenticator.initAdminUserIfNeeded(restConf); } finally { diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java index ae2c73e2c5..2652324f44 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java @@ -37,6 +37,7 @@ public class HugeGraphServer { private final RestServer restServer; private final GremlinServer gremlinServer; + private final MemoryMonitor memoryMonitor; public static void register() { RegisterUtil.registerBackends(); @@ -78,9 +79,15 @@ public HugeGraphServer(String gremlinServerConf, String restServerConf) } finally { System.setSecurityManager(securityManager); } + + // Start (In-Heap) Memory Monitor + this.memoryMonitor = new MemoryMonitor(restServerConf); + this.memoryMonitor.start(); } public void stop() { + this.memoryMonitor.stop(); + try { this.gremlinServer.stop().get(); LOG.info("HugeGremlinServer stopped"); diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java new file mode 100644 index 0000000000..18b7cc170f --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java @@ -0,0 +1,120 @@ +/* + * 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.dist; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryUsage; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.config.ServerOptions; +import org.apache.hugegraph.util.ExecutorUtil; +import org.apache.hugegraph.util.Log; +import org.slf4j.Logger; + +import com.sun.management.ThreadMXBean; + +public class MemoryMonitor { + + private static final Logger LOG = Log.logger(MemoryMonitor.class); + private final double MEMORY_MONITOR_THRESHOLD; + private final int MEMORY_MONITOR_DETECT_PERIOD; + private final ScheduledExecutorService scheduler; + + public MemoryMonitor(String restServerConf) { + HugeConfig restServerConfig = new HugeConfig(restServerConf); + MEMORY_MONITOR_THRESHOLD = + restServerConfig.get(ServerOptions.JVM_MEMORY_MONITOR_THRESHOLD); + MEMORY_MONITOR_DETECT_PERIOD = + restServerConfig.get(ServerOptions.JVM_MEMORY_MONITOR_DETECT_PERIOD); + this.scheduler = ExecutorUtil.newScheduledThreadPool("memory-monitor-thread-%d"); + } + + private void runMemoryDetect() { + double memoryUsagePercentage = getMemoryUsageRatio(); + + if (memoryUsagePercentage > MEMORY_MONITOR_THRESHOLD) { + LOG.warn("JVM memory usage is '{}', exceeding the threshold of '{}'.", + memoryUsagePercentage, MEMORY_MONITOR_THRESHOLD); + System.gc(); + LOG.warn("Trigger System.gc()"); + + double doubleCheckUsage = getMemoryUsageRatio(); + if (doubleCheckUsage > MEMORY_MONITOR_THRESHOLD) { + LOG.warn("JVM memory usage is '{}', exceeding the threshold of '{}'.", + doubleCheckUsage, MEMORY_MONITOR_THRESHOLD); + interruptHighestMemoryThread(); + } + } + } + + private double getMemoryUsageRatio() { + MemoryUsage heapMemoryUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + return (double) heapMemoryUsage.getUsed() / heapMemoryUsage.getMax(); + } + + private Thread getHighestMemoryThread() { + long highestMemory = 0; + Thread highestThread = null; + + ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); + + Thread[] threads = new Thread[Thread.activeCount()]; + Thread.enumerate(threads); + for (Thread thread : threads) { + if (thread.getState() != Thread.State.RUNNABLE || thread.getName() == null || + !thread.getName().startsWith("grizzly-http-server-")) { + continue; + } + + long threadMemory = threadMXBean.getThreadAllocatedBytes(thread.getId()); + if (threadMemory > highestMemory) { + highestMemory = threadMemory; + highestThread = thread; + } + } + return highestThread; + } + + private void interruptHighestMemoryThread() { + Thread targetThread = getHighestMemoryThread(); + if (targetThread != null) { + targetThread.interrupt(); + LOG.warn("Send interrupt to '{}' thread", targetThread.getName()); + } + } + + public void start() { + if (MEMORY_MONITOR_THRESHOLD >= 1.0) { + LOG.info("Invalid parameter, MEMORY_MONITOR_THRESHOLD should ≤ 1.0."); + return; + } + this.scheduler.scheduleAtFixedRate(this::runMemoryDetect, 0, MEMORY_MONITOR_DETECT_PERIOD, + TimeUnit.MILLISECONDS); + LOG.info("Memory monitoring started."); + } + + public void stop() { + if (MEMORY_MONITOR_THRESHOLD >= 1.0) { + return; + } + this.scheduler.shutdownNow(); + LOG.info("Memory monitoring stopped."); + } +} diff --git a/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example4.java b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example4.java new file mode 100644 index 0000000000..0416dd757f --- /dev/null +++ b/hugegraph-server/hugegraph-example/src/main/java/org/apache/hugegraph/example/Example4.java @@ -0,0 +1,363 @@ +/* + * 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.example; + +import java.util.Arrays; +import java.util.List; + +import org.apache.hugegraph.HugeFactory; +import org.apache.hugegraph.HugeGraph; +import org.apache.hugegraph.backend.BackendException; +import org.apache.hugegraph.backend.tx.GraphTransaction; +import org.apache.hugegraph.meta.MetaManager; +import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.schema.SchemaManager; +import org.apache.hugegraph.testutil.Whitebox; +import org.apache.hugegraph.util.Log; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.T; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.slf4j.Logger; + +import com.google.common.collect.ImmutableList; + +public class Example4 { + + /* This example serves a simple test of a parent-child type of EdgeLabel */ + private static final Logger LOG = Log.logger(Example4.class); + + private static final MetaManager metaManager = MetaManager.instance(); + + public static void main(String[] args) { + LOG.info( + "Example4 start! This example serves a simple test of a parent-child type of " + + "EdgeLabel"); + metaManager.connect("hg", MetaManager.MetaDriverType.PD, + null, null, null, + ImmutableList.of("127.0.0.1:8686")); + + HugeGraph graph = ExampleUtil.loadGraph(); + Example4.showFeatures(graph); + Example4.loadSchema(graph); + Example4.loadData(graph); + Example4.testQueryEdge(graph); + + try { + Example4.thread(graph); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + try { + graph.close(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + HugeFactory.shutdown(30L); + } + + private static void thread(HugeGraph graph) throws InterruptedException { + Thread t = new Thread(() -> { + // Default tx + graph.addVertex(T.label, "book", "name", "java-11"); + graph.addVertex(T.label, "book", "name", "java-12"); + graph.tx().commit(); + + // New tx + GraphTransaction tx = Whitebox.invoke(graph.getClass(), + "openGraphTransaction", + graph); + + tx.addVertex(T.label, "book", "name", "java-21"); + tx.addVertex(T.label, "book", "name", "java-22"); + tx.commit(); + tx.close(); + + // This will close the schema tx + Whitebox.invoke(graph.getClass(), "closeTx", graph); + }); + t.start(); + t.join(); + } + + public static void showFeatures(final HugeGraph graph) { + LOG.info("SupportsPersistence: {}", + graph.features().graph().supportsPersistence()); + } + + public static void loadSchema(final HugeGraph graph) { + + SchemaManager schema = graph.schema(); + // Schema changes will be commit directly into the back-end + LOG.info("=============== propertyKey ================"); + schema.propertyKey("id").asInt().create(); + schema.propertyKey("name").asText().create(); + schema.propertyKey("gender").asText().create(); + schema.propertyKey("instructions").asText().create(); + schema.propertyKey("category").asText().create(); + schema.propertyKey("year").asInt().create(); + schema.propertyKey("time").asText().create(); + schema.propertyKey("timestamp").asDate().create(); + schema.propertyKey("ISBN").asText().create(); + schema.propertyKey("calories").asInt().create(); + schema.propertyKey("amount").asText().create(); + schema.propertyKey("stars").asInt().create(); + schema.propertyKey("age").asInt().valueSingle().create(); + schema.propertyKey("comment").asText().valueSet().create(); + schema.propertyKey("contribution").asText().valueSet().create(); + schema.propertyKey("nickname").asText().valueList().create(); + schema.propertyKey("lived").asText().create(); + schema.propertyKey("country").asText().valueSet().create(); + schema.propertyKey("city").asText().create(); + schema.propertyKey("sensor_id").asUUID().create(); + schema.propertyKey("versions").asInt().valueList().create(); + + LOG.info("=============== vertexLabel ================"); + + schema.vertexLabel("person") + .properties("name", "age", "city") + .primaryKeys("name") + .create(); + schema.vertexLabel("author") + .properties("id", "name", "age", "lived") + .primaryKeys("id").create(); + schema.vertexLabel("language").properties("name", "versions") + .primaryKeys("name").create(); + schema.vertexLabel("recipe").properties("name", "instructions") + .primaryKeys("name").create(); + schema.vertexLabel("book").properties("name") + .primaryKeys("name").create(); + schema.vertexLabel("reviewer").properties("name", "timestamp") + .primaryKeys("name").create(); + + schema.vertexLabel("company") + .properties("name") + .primaryKeys("name").create(); + + // vertex label must have the properties that specified in primary key + schema.vertexLabel("FridgeSensor").properties("city") + .primaryKeys("city").create(); + + LOG.info("=============== vertexLabel & index ================"); + schema.indexLabel("personByCity") + .onV("person").secondary().by("city").create(); + schema.indexLabel("personByAge") + .onV("person").range().by("age").create(); + + schema.indexLabel("authorByLived") + .onV("author").search().by("lived").create(); + + LOG.info("=============== edgeLabel ================"); + + schema.edgeLabel("authored").singleTime() + .link("author", "book") + .properties("contribution", "comment") + .nullableKeys("comment") + .create(); + + // Create a parent EdgeLabel + EdgeLabel elFather = schema.edgeLabel("transfer").asBase().create(); + + LOG.info(String.format("Parent type created: %s, its id is: %s", + elFather.name(), elFather.id().asString())); + + // Create two child EdgeLabels + EdgeLabel son1 = + schema.edgeLabel("transfer-1").withBase("transfer").multiTimes() + .link("author", "person") + .properties("time").sortKeys("time").create(); + + LOG.info(String.format("Child type created: %s, its id is: %s, its parent id is %s", + son1.name(), son1.id().asString(), + son1.fatherId().asString())); + + EdgeLabel son2 = + schema.edgeLabel("transfer-2").withBase("transfer").multiTimes() + .link("author", "company") + .properties("time").sortKeys("time").create(); + + LOG.info(String.format("Child type created: %s, its id is: %s, its parent id is %s", + son2.name(), son2.id().asString(), + son2.fatherId().asString())); + + schema.edgeLabel("write").multiTimes().properties("time") + .link("author", "book") + .sortKeys("time") + .create(); + + schema.edgeLabel("look").multiTimes().properties("timestamp") + .link("person", "book") + .sortKeys("timestamp") + .create(); + + schema.edgeLabel("created").singleTime() + .link("author", "language") + .create(); + + schema.edgeLabel("rated") + .link("reviewer", "recipe") + .create(); + } + + public static void loadData(final HugeGraph graph) { + // will auto open tx (would not auto commit) + graph.addVertex(T.label, "book", "name", "java-3"); + + graph.addVertex(T.label, "person", "name", "Baby", + "city", "Hongkong", "age", 3); + graph.addVertex(T.label, "person", "name", "James", + "city", "Beijing", "age", 19); + graph.addVertex(T.label, "person", "name", "Tom Cat", + "city", "Beijing", "age", 20); + graph.addVertex(T.label, "person", "name", "Lisa", + "city", "Beijing", "age", 20); + graph.addVertex(T.label, "person", "name", "Hebe", + "city", "Taipei", "age", 21); + + graph.tx().commit(); + + // must commit manually with new backend tx (independent of tinkerpop) + GraphTransaction tx = Whitebox.invoke(graph.getClass(), + "openGraphTransaction", + graph); + + LOG.info("=============== addVertex ================"); + Vertex james = tx.addVertex(T.label, "author", "id", 1, + "name", "James Gosling", "age", 62, + "lived", "San Francisco Bay Area"); + + Vertex java = tx.addVertex(T.label, "language", "name", "java", + "versions", Arrays.asList(6, 7, 8)); + Vertex book1 = tx.addVertex(T.label, "book", "name", "java-1"); + Vertex book2 = tx.addVertex(T.label, "book", "name", "java-2"); + Vertex book3 = tx.addVertex(T.label, "book", "name", "java-3"); + + Vertex baidu = tx.addVertex(T.label, "company", "name", "baidu"); + Vertex yanHong = tx.addVertex(T.label, "person", "name", "yanHong", + "city", "Beijing", "age", 45); + + Edge edgeTransfer1 = + james.addEdge("transfer-1", yanHong, "time", "2022-1-1"); + james.addEdge("transfer-1", yanHong, "time", "2022-1-2"); + james.addEdge("transfer-1", yanHong, "time", "2022-1-3"); + + Edge edgeTransfer2 = + james.addEdge("transfer-2", baidu, "time", "2022-2-2"); + james.addEdge("transfer-2", baidu, "time", "2022-2-1"); + james.addEdge("transfer-2", baidu, "time", "2022-2-2"); + james.addEdge("transfer-2", baidu, "time", "2022-2-3"); + james.addEdge("created", java); + james.addEdge("authored", book1, + "contribution", "1990-1-1", + "comment", "it's a good book", + "comment", "it's a good book", + "comment", "it's a good book too"); + james.addEdge("authored", book2, "contribution", "2017-4-28"); + + Edge edge1 = james.addEdge("write", book2, "time", "2017-4-28"); + Edge edge2 = james.addEdge("write", book3, "time", "2016-1-1"); + Edge edge3 = james.addEdge("write", book3, "time", "2017-4-28"); + + // commit data changes + try { + tx.commit(); + } catch (BackendException e) { + e.printStackTrace(); + try { + tx.rollback(); + } catch (BackendException e2) { + e2.printStackTrace(); + } + } finally { + tx.close(); + } + + // use the manually open transaction (tinkerpop tx) + graph.tx().open(); + graph.addVertex(T.label, "book", "name", "java-3"); + graph.addVertex(T.label, "book", "name", "java-4"); + Vertex vertex1 = graph.addVertex(T.label, "book", "name", "java-5"); + System.out.println(vertex1.id().toString()); + + graph.tx().commit(); + } + + public static void testQueryEdge(final HugeGraph graph) { + GraphTraversal edges = graph.traversal().E(); + List list = edges.toList(); + + GraphTraversal vertexs = graph.traversal().V(); + List list1 = vertexs.toList(); + + GraphTraversal vertexEdgeGraphTraversal = + graph.traversal().V("2:11").outE("write"); + LOG.info("The number of write edges is: " + vertexEdgeGraphTraversal.toList().size()); + + // Three types of queries + // First, query edges for person-to-person transfers + GraphTraversal transfer1 = + graph.traversal().V("2:11").outE("transfer-1") + .has("time", "2022-1-2"); + // transfer_1.toList().size(); + LOG.info("The number of person-to-person transfer edges (transfer1) for james is: " + transfer1.toList().size()); + + // Second, query edges for person-to-company transfers + GraphTraversal transfer2 = + graph.traversal().V("2:11").outE("transfer-2"); + // transfer_2.toList().size(); + LOG.info("The number of person-to-company transfer edges (transfer2) for james is: " + transfer2.toList().size()); + + // Third, query transfer edges + GraphTraversal transfer = + graph.traversal().V("2:11").outE("transfer"); + // transfer.toList().size(); + LOG.info("The number of transfer edges (transfer) is: " + transfer.toList().size()); + + GraphTraversal writeAndTransfer1 = + graph.traversal().V("2:11").outE("write", "transfer-1"); + LOG.info( + "Mixed query: graph.traversal().V(\"2:11\").outE(\"write\", \"transfer-1\") => The total number of write and transfer1 edges is: " + + writeAndTransfer1.toList().size()); + + GraphTraversal writeAndTransfer1WithLimit = + graph.traversal().V("2:11") + .outE("write", "transfer-1") + .limit(2); + LOG.info( + "Limited mixed query: graph.traversal().V(\"2:11\").outE(\"write\", \"transfer-1\").limit(2); => " + + "The total number of write and transfer1 edges is: " + + writeAndTransfer1WithLimit.toList().size()); + + GraphTraversal res = graph.traversal().V("2:11") + .outE("write", "transfer-1", + "transfer-2", "transfer"); + LOG.info( + "Mixed query: graph.traversal().V(\"2:11\").outE(\"write\", \"transfer-1\", " + + "\"transfer-2\", \"transfer\") The total number of edges is: " + + res.toList().size()); + + System.out.println("graph.traversal().E().hasLabel(\"write\").toList" + + "().size():" + + graph.traversal().E().hasLabel("write").toList() + .size()); + + } +} + diff --git a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreStore.java b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreStore.java index 954fe35076..6439096674 100644 --- a/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreStore.java +++ b/hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreStore.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; @@ -29,12 +30,18 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; +import com.google.common.collect.Lists; + import org.apache.commons.collections.CollectionUtils; +import org.apache.hugegraph.HugeGraph; import org.apache.hugegraph.backend.id.Id; import org.apache.hugegraph.backend.id.IdGenerator; +import org.apache.hugegraph.backend.query.ConditionQuery; +import org.apache.hugegraph.backend.query.ConditionQueryFlatten; import org.apache.hugegraph.backend.query.IdPrefixQuery; import org.apache.hugegraph.backend.query.IdQuery; import org.apache.hugegraph.backend.query.Query; @@ -52,10 +59,12 @@ import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.iterator.CIter; +import org.apache.hugegraph.schema.EdgeLabel; import org.apache.hugegraph.type.HugeTableType; import org.apache.hugegraph.type.HugeType; import org.apache.hugegraph.type.define.Action; import org.apache.hugegraph.type.define.GraphMode; +import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.util.E; import org.apache.hugegraph.util.Log; import org.slf4j.Logger; @@ -339,161 +348,160 @@ public Iterator query(Query query) { } } - // TODO: uncomment later - sub edge labels - //@Override - //public Iterator> query(Iterator queries, - // Function queryWriter, - // HugeGraph hugeGraph) { - // if (queries == null || !queries.hasNext()) { - // return Collections.emptyIterator(); - // } - // - // class QueryWrapper implements Iterator { - // Query first; - // final Iterator queries; - // Iterator subEls; - // Query preQuery; - // Iterator queryListIterator; - // - // QueryWrapper(Iterator queries, Query first) { - // this.queries = queries; - // this.first = first; - // } - // - // @Override - // public boolean hasNext() { - // return first != null || (this.subEls != null && this.subEls.hasNext()) - // || (queryListIterator != null && queryListIterator.hasNext()) || - // queries.hasNext(); - // } - // - // @Override - // public IdPrefixQuery next() { - // if (queryListIterator != null && queryListIterator.hasNext()) { - // return queryListIterator.next(); - // } - // - // Query q; - // if (first != null) { - // q = first; - // preQuery = q.copy(); - // first = null; - // } else { - // if (this.subEls == null || !this.subEls.hasNext()) { - // q = queries.next(); - // preQuery = q.copy(); - // } else { - // q = preQuery.copy(); - // } - // } - // - // assert q instanceof ConditionQuery; - // ConditionQuery cq = (ConditionQuery) q; - // ConditionQuery originQuery = (ConditionQuery) q.copy(); - // - // List queryList = Lists.newArrayList(); - // if (hugeGraph != null) { - // for (ConditionQuery conditionQuery : - // ConditionQueryFlatten.flatten(cq)) { - // Id label = conditionQuery.condition(HugeKeys.LABEL); - // /* Parent type + sortKeys: g.V("V.id").outE("parentLabel").has - // ("sortKey","value") converted to all subtypes + sortKeys */ - // if ((this.subEls == null || - // !this.subEls.hasNext()) && label != null && - // hugeGraph.edgeLabel(label).isFather() && - // conditionQuery.condition(HugeKeys.SUB_LABEL) == - // null && - // conditionQuery.condition(HugeKeys.OWNER_VERTEX) != - // null && - // conditionQuery.condition(HugeKeys.DIRECTION) != - // null && - // matchEdgeSortKeys(conditionQuery, false, - // hugeGraph)) { - // this.subEls = - // getSubLabelsOfParentEl( - // hugeGraph.edgeLabels(), - // label); - // } - // - // if (this.subEls != null && - // this.subEls.hasNext()) { - // conditionQuery.eq(HugeKeys.SUB_LABEL, - // subEls.next()); - // } - // - // HugeType hugeType = conditionQuery.resultType(); - // if (hugeType != null && hugeType.isEdge() && - // !conditionQuery.conditions().isEmpty()) { - // IdPrefixQuery idPrefixQuery = - // (IdPrefixQuery) queryWriter.apply( - // conditionQuery); - // idPrefixQuery.setOriginQuery(originQuery); - // queryList.add(idPrefixQuery); - // } - // } - // - // queryListIterator = queryList.iterator(); - // if (queryListIterator.hasNext()) { - // return queryListIterator.next(); - // } - // } - // - // Id ownerId = cq.condition(HugeKeys.OWNER_VERTEX); - // assert ownerId != null; - // BytesBuffer buffer = - // BytesBuffer.allocate(BytesBuffer.BUF_EDGE_ID); - // buffer.writeId(ownerId); - // return new IdPrefixQuery(cq, new BinaryBackendEntry.BinaryId( - // buffer.bytes(), ownerId)); - // } - // - // private boolean matchEdgeSortKeys(ConditionQuery query, - // boolean matchAll, - // HugeGraph graph) { - // assert query.resultType().isEdge(); - // Id label = query.condition(HugeKeys.LABEL); - // if (label == null) { - // return false; - // } - // List sortKeys = graph.edgeLabel(label).sortKeys(); - // if (sortKeys.isEmpty()) { - // return false; - // } - // Set queryKeys = query.userpropKeys(); - // for (int i = sortKeys.size(); i > 0; i--) { - // List subFields = sortKeys.subList(0, i); - // if (queryKeys.containsAll(subFields)) { - // if (queryKeys.size() == subFields.size() || !matchAll) { - // /* - // * Return true if: - // * matchAll=true and all queryKeys are in sortKeys - // * or - // * partial queryKeys are in sortKeys - // */ - // return true; - // } - // } - // } - // return false; - // } - // } - // Query first = queries.next(); - // List typeList = getHugeTypes(first); - // QueryWrapper idPrefixQueries = new QueryWrapper(queries, first); - // - // return query(typeList, idPrefixQueries); - //} - - //private Iterator getSubLabelsOfParentEl(Collection allEls, - // Id label) { - // List list = new ArrayList<>(); - // for (EdgeLabel el : allEls) { - // if (el.edgeLabelType().sub() && el.fatherId().equals(label)) { - // list.add(el.id()); - // } - // } - // return list.iterator(); - //} + @Override + public Iterator> query(Iterator queries, + Function queryWriter, + HugeGraph hugeGraph) { + if (queries == null || !queries.hasNext()) { + return Collections.emptyIterator(); + } + + class QueryWrapper implements Iterator { + Query first; + final Iterator queries; + Iterator subEls; + Query preQuery; + Iterator queryListIterator; + + QueryWrapper(Iterator queries, Query first) { + this.queries = queries; + this.first = first; + } + + @Override + public boolean hasNext() { + return first != null || (this.subEls != null && this.subEls.hasNext()) + || (queryListIterator != null && queryListIterator.hasNext()) || + queries.hasNext(); + } + + @Override + public IdPrefixQuery next() { + if (queryListIterator != null && queryListIterator.hasNext()) { + return queryListIterator.next(); + } + + Query q; + if (first != null) { + q = first; + preQuery = q.copy(); + first = null; + } else { + if (this.subEls == null || !this.subEls.hasNext()) { + q = queries.next(); + preQuery = q.copy(); + } else { + q = preQuery.copy(); + } + } + + assert q instanceof ConditionQuery; + ConditionQuery cq = (ConditionQuery) q; + ConditionQuery originQuery = (ConditionQuery) q.copy(); + + List queryList = Lists.newArrayList(); + if (hugeGraph != null) { + for (ConditionQuery conditionQuery : + ConditionQueryFlatten.flatten(cq)) { + Id label = conditionQuery.condition(HugeKeys.LABEL); + /* Parent type + sortKeys: g.V("V.id").outE("parentLabel") + .has("sortKey","value") converted to all subtypes + sortKeys */ + if ((this.subEls == null || + !this.subEls.hasNext()) && label != null && + hugeGraph.edgeLabel(label).isFather() && + conditionQuery.condition(HugeKeys.SUB_LABEL) == + null && + conditionQuery.condition(HugeKeys.OWNER_VERTEX) != + null && + conditionQuery.condition(HugeKeys.DIRECTION) != + null && + matchEdgeSortKeys(conditionQuery, false, + hugeGraph)) { + this.subEls = + getSubLabelsOfParentEl( + hugeGraph.edgeLabels(), + label); + } + + if (this.subEls != null && + this.subEls.hasNext()) { + conditionQuery.eq(HugeKeys.SUB_LABEL, + subEls.next()); + } + + HugeType hugeType = conditionQuery.resultType(); + if (hugeType != null && hugeType.isEdge() && + !conditionQuery.conditions().isEmpty()) { + IdPrefixQuery idPrefixQuery = + (IdPrefixQuery) queryWriter.apply( + conditionQuery); + idPrefixQuery.setOriginQuery(originQuery); + queryList.add(idPrefixQuery); + } + } + + queryListIterator = queryList.iterator(); + if (queryListIterator.hasNext()) { + return queryListIterator.next(); + } + } + + Id ownerId = cq.condition(HugeKeys.OWNER_VERTEX); + assert ownerId != null; + BytesBuffer buffer = + BytesBuffer.allocate(BytesBuffer.BUF_EDGE_ID); + buffer.writeId(ownerId); + return new IdPrefixQuery(cq, new BinaryBackendEntry.BinaryId( + buffer.bytes(), ownerId)); + } + + private boolean matchEdgeSortKeys(ConditionQuery query, + boolean matchAll, + HugeGraph graph) { + assert query.resultType().isEdge(); + Id label = query.condition(HugeKeys.LABEL); + if (label == null) { + return false; + } + List sortKeys = graph.edgeLabel(label).sortKeys(); + if (sortKeys.isEmpty()) { + return false; + } + Set queryKeys = query.userpropKeys(); + for (int i = sortKeys.size(); i > 0; i--) { + List subFields = sortKeys.subList(0, i); + if (queryKeys.containsAll(subFields)) { + if (queryKeys.size() == subFields.size() || !matchAll) { + /* + * Return true if: + * matchAll=true and all queryKeys are in sortKeys + * or + * partial queryKeys are in sortKeys + */ + return true; + } + } + } + return false; + } + } + Query first = queries.next(); + List typeList = getHugeTypes(first); + QueryWrapper idPrefixQueries = new QueryWrapper(queries, first); + + return query(typeList, idPrefixQueries); + } + + private Iterator getSubLabelsOfParentEl(Collection allEls, + Id label) { + List list = new ArrayList<>(); + for (EdgeLabel el : allEls) { + if (el.edgeLabelType().sub() && el.fatherId().equals(label)) { + list.add(el.id()); + } + } + return list.iterator(); + } public List> query(List typeList, List queries) { diff --git a/hugegraph-server/hugegraph-mysql/src/main/java/org/apache/hugegraph/backend/store/mysql/MysqlSerializer.java b/hugegraph-server/hugegraph-mysql/src/main/java/org/apache/hugegraph/backend/store/mysql/MysqlSerializer.java index 1557902bd2..595ab609bd 100644 --- a/hugegraph-server/hugegraph-mysql/src/main/java/org/apache/hugegraph/backend/store/mysql/MysqlSerializer.java +++ b/hugegraph-server/hugegraph-mysql/src/main/java/org/apache/hugegraph/backend/store/mysql/MysqlSerializer.java @@ -27,7 +27,7 @@ import org.apache.hugegraph.backend.id.Id; import org.apache.hugegraph.backend.id.IdGenerator; import org.apache.hugegraph.backend.serializer.TableBackendEntry; -import org.apache.hugegraph.backend.serializer.TableSerializer; +import org.apache.hugegraph.backend.serializer.TableSerializerV2; import org.apache.hugegraph.backend.store.BackendEntry; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.schema.SchemaElement; @@ -39,7 +39,7 @@ import org.apache.hugegraph.util.InsertionOrderUtil; import org.apache.hugegraph.util.JsonUtil; -public class MysqlSerializer extends TableSerializer { +public class MysqlSerializer extends TableSerializerV2 { public MysqlSerializer(HugeConfig config) { super(config); diff --git a/hugegraph-server/hugegraph-mysql/src/main/java/org/apache/hugegraph/backend/store/mysql/MysqlTables.java b/hugegraph-server/hugegraph-mysql/src/main/java/org/apache/hugegraph/backend/store/mysql/MysqlTables.java index cf0a1e08e3..981369f56d 100644 --- a/hugegraph-server/hugegraph-mysql/src/main/java/org/apache/hugegraph/backend/store/mysql/MysqlTables.java +++ b/hugegraph-server/hugegraph-mysql/src/main/java/org/apache/hugegraph/backend/store/mysql/MysqlTables.java @@ -333,12 +333,13 @@ public Edge(String store, Directions direction, this.define.column(HugeKeys.OWNER_VERTEX, SMALL_TEXT); this.define.column(HugeKeys.DIRECTION, TINYINT); this.define.column(HugeKeys.LABEL, DATATYPE_SL); + this.define.column(HugeKeys.SUB_LABEL, DATATYPE_SL); this.define.column(HugeKeys.SORT_VALUES, SMALL_TEXT); this.define.column(HugeKeys.OTHER_VERTEX, SMALL_TEXT); this.define.column(HugeKeys.PROPERTIES, LARGE_JSON); this.define.column(HugeKeys.EXPIRED_TIME, BIGINT); this.define.keys(HugeKeys.OWNER_VERTEX, HugeKeys.DIRECTION, - HugeKeys.LABEL, HugeKeys.SORT_VALUES, + HugeKeys.LABEL, HugeKeys.SUB_LABEL, HugeKeys.SORT_VALUES, HugeKeys.OTHER_VERTEX); } @@ -365,6 +366,7 @@ public List idColumnValue(Id id) { list.add(IdUtil.writeStoredString(edgeId.ownerVertexId())); list.add(edgeId.directionCode()); list.add(edgeId.edgeLabelId().asLong()); + list.add(edgeId.subLabelId().asLong()); list.add(edgeId.sortValues()); list.add(IdUtil.writeStoredString(edgeId.otherVertexId())); return list; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/ApiTestSuite.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/ApiTestSuite.java index 11d3e64095..cca27a78c2 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/ApiTestSuite.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/ApiTestSuite.java @@ -17,6 +17,7 @@ package org.apache.hugegraph.api; +import org.apache.hugegraph.api.graphspaces.GraphSpaceApiTestSuite; import org.apache.hugegraph.api.traversers.TraversersApiTestSuite; import org.apache.hugegraph.dist.RegisterUtil; import org.junit.BeforeClass; @@ -40,7 +41,8 @@ ProjectApiTest.class, TraversersApiTestSuite.class, CypherApiTest.class, - ArthasApiTest.class + ArthasApiTest.class, + GraphSpaceApiTestSuite.class }) public class ApiTestSuite { diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/BaseApiTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/BaseApiTest.java index 4b6c0ed7f4..72821ecb1a 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/BaseApiTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/BaseApiTest.java @@ -55,7 +55,7 @@ public class BaseApiTest { - private static final String BASE_URL = "http://127.0.0.1:8080"; + protected static final String BASE_URL = "http://127.0.0.1:8080"; private static final String GRAPH = "hugegraph"; private static final String USERNAME = "admin"; private static final String PASSWORD = "pa"; @@ -71,7 +71,7 @@ public class BaseApiTest { protected static final String TRAVERSERS_API = URL_PREFIX + "/traversers"; - private static RestClient client; + protected static RestClient client; private static final ObjectMapper MAPPER = new ObjectMapper(); @@ -84,6 +84,7 @@ public static void init() { @AfterClass public static void clear() throws Exception { client.close(); + client = null; } @After diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceApiTestSuite.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceApiTestSuite.java new file mode 100644 index 0000000000..d5090058b1 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceApiTestSuite.java @@ -0,0 +1,34 @@ +/* + * 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.api.graphspaces; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + GraphSpacePropertyKeyApiTest.class, + GraphSpaceVertexLabelApiTest.class, + GraphSpaceEdgeLabelApiTest.class, + GraphSpaceIndexLabelApiTest.class, + GraphSpaceEdgeApiTest.class, + GraphSpaceVertexApiTest.class +}) +public class GraphSpaceApiTestSuite { + +} diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceEdgeApiTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceEdgeApiTest.java new file mode 100644 index 0000000000..643888a953 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceEdgeApiTest.java @@ -0,0 +1,36 @@ +/* + * 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.api.graphspaces; + +import java.util.Objects; + +import org.apache.hugegraph.api.BaseApiTest; +import org.apache.hugegraph.api.EdgeApiTest; +import org.junit.BeforeClass; + +public class GraphSpaceEdgeApiTest extends EdgeApiTest { + + @BeforeClass + public static void init() { + if (Objects.nonNull(client)) { + client.close(); + } + client = new RestClient(String.join("/", BASE_URL, "graphspaces", "DEFAULT")); + BaseApiTest.clearData(); + } +} diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceEdgeLabelApiTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceEdgeLabelApiTest.java new file mode 100644 index 0000000000..80e21b1631 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceEdgeLabelApiTest.java @@ -0,0 +1,36 @@ +/* + * 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.api.graphspaces; + +import java.util.Objects; + +import org.apache.hugegraph.api.BaseApiTest; +import org.apache.hugegraph.api.EdgeLabelApiTest; +import org.junit.BeforeClass; + +public class GraphSpaceEdgeLabelApiTest extends EdgeLabelApiTest { + + @BeforeClass + public static void init() { + if (Objects.nonNull(client)) { + client.close(); + } + client = new RestClient(String.join("/", BASE_URL, "graphspaces", "DEFAULT")); + BaseApiTest.clearData(); + } +} diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceIndexLabelApiTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceIndexLabelApiTest.java new file mode 100644 index 0000000000..f5f3e4c4d8 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceIndexLabelApiTest.java @@ -0,0 +1,36 @@ +/* + * 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.api.graphspaces; + +import java.util.Objects; + +import org.apache.hugegraph.api.BaseApiTest; +import org.apache.hugegraph.api.IndexLabelApiTest; +import org.junit.BeforeClass; + +public class GraphSpaceIndexLabelApiTest extends IndexLabelApiTest { + + @BeforeClass + public static void init() { + if (Objects.nonNull(client)) { + client.close(); + } + client = new RestClient(String.join("/", BASE_URL, "graphspaces", "DEFAULT")); + BaseApiTest.clearData(); + } +} diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpacePropertyKeyApiTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpacePropertyKeyApiTest.java new file mode 100644 index 0000000000..6096c10ee2 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpacePropertyKeyApiTest.java @@ -0,0 +1,36 @@ +/* + * 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.api.graphspaces; + +import java.util.Objects; + +import org.apache.hugegraph.api.BaseApiTest; +import org.apache.hugegraph.api.PropertyKeyApiTest; +import org.junit.BeforeClass; + +public class GraphSpacePropertyKeyApiTest extends PropertyKeyApiTest { + + @BeforeClass + public static void init() { + if (Objects.nonNull(client)) { + client.close(); + } + client = new RestClient(String.join("/", BASE_URL, "graphspaces", "DEFAULT")); + BaseApiTest.clearData(); + } +} diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceVertexApiTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceVertexApiTest.java new file mode 100644 index 0000000000..f967540e1d --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceVertexApiTest.java @@ -0,0 +1,36 @@ +/* + * 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.api.graphspaces; + +import java.util.Objects; + +import org.apache.hugegraph.api.BaseApiTest; +import org.apache.hugegraph.api.VertexApiTest; +import org.junit.BeforeClass; + +public class GraphSpaceVertexApiTest extends VertexApiTest { + + @BeforeClass + public static void init() { + if (Objects.nonNull(client)) { + client.close(); + } + client = new RestClient(String.join("/", BASE_URL, "graphspaces", "DEFAULT")); + BaseApiTest.clearData(); + } +} diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceVertexLabelApiTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceVertexLabelApiTest.java new file mode 100644 index 0000000000..5b12576a67 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/api/graphspaces/GraphSpaceVertexLabelApiTest.java @@ -0,0 +1,36 @@ +/* + * 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.api.graphspaces; + +import java.util.Objects; + +import org.apache.hugegraph.api.BaseApiTest; +import org.apache.hugegraph.api.VertexLabelApiTest; +import org.junit.BeforeClass; + +public class GraphSpaceVertexLabelApiTest extends VertexLabelApiTest { + + @BeforeClass + public static void init() { + if (Objects.nonNull(client)) { + client.close(); + } + client = new RestClient(String.join("/", BASE_URL, "graphspaces", "DEFAULT")); + BaseApiTest.clearData(); + } +} diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/BaseCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/BaseCoreTest.java index a042533843..fabd622b8a 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/BaseCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/BaseCoreTest.java @@ -17,6 +17,7 @@ package org.apache.hugegraph.core; +import java.util.List; import java.util.Random; import org.apache.hugegraph.HugeGraph; @@ -25,6 +26,7 @@ import org.apache.hugegraph.backend.store.BackendFeatures; import org.apache.hugegraph.dist.RegisterUtil; import org.apache.hugegraph.masterelection.GlobalMasterInfo; +import org.apache.hugegraph.schema.EdgeLabel; import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.testutil.Utils; import org.apache.hugegraph.testutil.Whitebox; @@ -137,7 +139,21 @@ private void clearSchema() { schema.indexLabel(elem.name()).remove(); }); - schema.getEdgeLabels().forEach(elem -> { + final List edgeLabels = schema.getEdgeLabels(); + // remove father edge label after sub edge label + edgeLabels.sort((lhs, rhs) -> { + if (lhs.isFather() && rhs.isFather()) { + return 0; + } + if (lhs.isFather()) { + return 1; + } + if (rhs.isFather()) { + return -1; + } + return 0; + }); + edgeLabels.forEach(elem -> { schema.edgeLabel(elem.name()).remove(); }); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CoreTestSuite.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CoreTestSuite.java index 17e01a4fab..4c832b544c 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CoreTestSuite.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CoreTestSuite.java @@ -30,6 +30,7 @@ IndexLabelCoreTest.class, VertexCoreTest.class, EdgeCoreTest.class, + ParentAndSubEdgeCoreTest.class, VertexPropertyCoreTest.class, EdgePropertyCoreTest.class, RestoreCoreTest.class, diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java index b79cae1963..265d408742 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java @@ -75,7 +75,6 @@ import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils; import org.junit.Assume; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import com.google.common.collect.ImmutableList; @@ -470,12 +469,13 @@ public void testAddEdgeWithLargeSortkey() { Vertex book = graph.addVertex(T.label, "book", "name", "Test-Book-1"); Assert.assertThrows(IllegalArgumentException.class, () -> { - final int LEN = BytesBuffer.BIG_ID_LEN_MAX; + final int LEN = BytesBuffer.EID_LEN_MAX; String largeTime = "{large-time}" + new String(new byte[LEN]); james.addEdge("write", book, "time", largeTime); graph.tx().commit(); }, e -> { - Assert.assertContains("The max length of edge id is 32768", + Assert.assertContains(String.format("The max length of edge id is %s", + BytesBuffer.EID_LEN_MAX), e.getMessage()); }); } diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/ParentAndSubEdgeCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/ParentAndSubEdgeCoreTest.java new file mode 100644 index 0000000000..4d7cc3eea3 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/ParentAndSubEdgeCoreTest.java @@ -0,0 +1,375 @@ +/* + * 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.core; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hugegraph.HugeGraph; +import org.apache.hugegraph.schema.EdgeLabel; +import org.apache.hugegraph.schema.SchemaManager; +import org.apache.hugegraph.testutil.Assert; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.T; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +public class ParentAndSubEdgeCoreTest extends BaseCoreTest { + + @Before + public void initSchema() { + Assume.assumeTrue("Not support father and sub edge label", + this.storeFeatures().supportsFatherAndSubEdgeLabel()); + + SchemaManager schema = graph().schema(); + + LOG.debug("=============== propertyKey ================"); + + schema.propertyKey("id").asInt().create(); + schema.propertyKey("name").asText().create(); + schema.propertyKey("time").asText().create(); + schema.propertyKey("timestamp").asLong().create(); + schema.propertyKey("age").asInt().valueSingle().create(); + schema.propertyKey("comment").asText().valueSet().create(); + schema.propertyKey("contribution").asText().create(); + schema.propertyKey("score").asInt().create(); + schema.propertyKey("lived").asText().create(); + schema.propertyKey("city").asText().create(); + schema.propertyKey("amount").asFloat().create(); + + LOG.debug("=============== vertexLabel ================"); + + schema.vertexLabel("person") + .properties("name", "age", "city") + .primaryKeys("name") + .enableLabelIndex(false) + .create(); + + schema.vertexLabel("company") + .properties("name", "city") + .primaryKeys("name") + .enableLabelIndex(false) + .create(); + + schema.vertexLabel("author") + .properties("id", "name", "age", "lived") + .primaryKeys("id") + .enableLabelIndex(false) + .create(); + + LOG.debug("=============== edgeLabel ================"); + + EdgeLabel elFather = + schema.edgeLabel("transfer").asBase() + .properties("time", "amount") + .multiTimes() + .sortKeys("time") + .create(); + + EdgeLabel transfer1 = schema.edgeLabel("transfer-1") + .withBase("transfer").multiTimes() + .link("person", "person") + .properties("time", "amount") + .sortKeys("time") + .create(); + + EdgeLabel transfer2 = schema.edgeLabel("transfer-2") + .withBase("transfer").multiTimes() + .link("person", "company") + .properties("time", "amount") + .sortKeys("time") + .create(); + + EdgeLabel transfer3 = schema.edgeLabel("transfer-3") + .withBase("transfer").multiTimes() + .link("person", "author") + .properties("time", "amount") + .sortKeys("time") + .create(); + + graph().schema().indexLabel("transferByAmount").onE("transfer") + .by("amount").secondary().ifNotExist().create(); + graph().schema().indexLabel("transfer-1ByAmount").onE("transfer-1") + .by("amount").secondary().ifNotExist().create(); + graph().schema().indexLabel("transfer-2ByAmount").onE("transfer-2") + .by("amount").secondary().ifNotExist().create(); + graph().schema().indexLabel("transfer-3ByAmount").onE("transfer-3") + .by("amount").secondary().ifNotExist().create(); + + schema.edgeLabel("know").multiTimes() + .sourceLabel("person") + .targetLabel("person") + .enableLabelIndex(true) + .properties("time") + .sortKeys("time") + .create(); + + graph().schema().indexLabel("knowByTime").onE("know") + .by("time").secondary().ifNotExist().create(); + } + + private List init10Edges() { + HugeGraph graph = graph(); + + Vertex person1 = graph.addVertex(T.label, "person", + "age", 19, + "city", "Beijing", + "name", "person1"); + Vertex person2 = graph.addVertex(T.label, "person", + "age", 20, + "city", "Shanghai", + "name", "person2"); + Vertex person3 = graph.addVertex(T.label, "person", + "age", 19, + "city", "Nanjing", + "name", "person3"); + + Vertex baidu = graph.addVertex(T.label, "company", + "name", "Baidu", + "city", "Beijing"); + Vertex huawei = graph.addVertex(T.label, "company", + "name", "Huawei", + "city", "Shanghai"); + Vertex tencent = graph.addVertex(T.label, "company", + "name", "Tencent", + "city", "Shenzhen"); + + Vertex james = graph.addVertex(T.label, "author", "id", 1, + "name", "James Gosling", "age", 62, + "lived", "Canadian"); + Vertex guido = graph.addVertex(T.label, "author", "id", 2, + "name", "Guido van Rossum", "age", 61, + "lived", "California"); + + person1.addEdge("transfer-1", person2, "time", "2021-11-11", + "amount", 9.00); + person1.addEdge("transfer-1", person3, "time", "2021-11-22", + "amount", 10.00); + + person2.addEdge("transfer-1", person3, "time", "2022-1-1", + "amount", 10.00); + person2.addEdge("transfer-1", person3, "time", "2022-1-2", + "amount", 10.00); + + person2.addEdge("transfer-2", baidu, "time", "2022-1-1", + "amount", 10.00); + person2.addEdge("transfer-2", baidu, "time", "2022-1-2", + "amount", 10.00); + person2.addEdge("transfer-2", baidu, "time", "2022-1-3", + "amount", 10.00); + + person3.addEdge("transfer-2", baidu, "time", "2022-1-4", + "amount", 10.00); + person3.addEdge("transfer-2", tencent, "time", "2022-1-1", + "amount", 10.00); + person3.addEdge("transfer-2", tencent, "time", "2022-1-2", + "amount", 9.00); + + person1.addEdge("know", person2, "time", "2022-1-1"); + + graph.tx().commit(); + List list = new ArrayList<>(); + list.add(person1); + list.add(person2); + list.add(person3); + return list; + } + + @Test + public void testQueryParentAndSubEdgesWithHasLabel() { + Assume.assumeTrue("Not support father and sub edge label", + this.storeFeatures().supportsFatherAndSubEdgeLabel()); + + // Simple hasLabel Type Query + init10Edges(); + + // normal edge + List edges = graph().traversal().E().hasLabel("know").toList(); + Assert.assertEquals(1, edges.size()); + + // father edge + edges = graph().traversal().E().hasLabel("transfer").toList(); + Assert.assertEquals(10, edges.size()); + + // sub edge + edges = graph().traversal().E().hasLabel("transfer-1").toList(); + Assert.assertEquals(4, edges.size()); + + edges = graph().traversal().E().hasLabel("transfer-2").toList(); + Assert.assertEquals(6, edges.size()); + } + + @Test + public void testQueryParentAndSubEdgesWithHasLabelAndConditions() { + Assume.assumeTrue("Not support father and sub edge label", + this.storeFeatures().supportsFatherAndSubEdgeLabel()); + + // hasLabel + Conditional Filtering Type Query + init10Edges(); + + // normal edge + List edges = graph().traversal().E().hasLabel("know") + .has("time", "2022-1-1") + .toList(); + + Assert.assertEquals(1, edges.size()); + + // father edge + edges = graph().traversal().E().hasLabel("transfer").has("amount", + 10.00).toList(); + + Assert.assertEquals(8, edges.size()); + + // sub edge + edges = graph().traversal().E().hasLabel("transfer-1") + .has("amount", 10.00) + .toList(); + Assert.assertEquals(3, edges.size()); + + edges = graph().traversal().E().hasLabel("transfer-2") + .has("amount", 10.00) + .toList(); + Assert.assertEquals(5, edges.size()); + } + + @Test + public void testQueryParentAndSubEdgesWithVertexOut() { + Assume.assumeTrue("Not support father and sub edge label", + this.storeFeatures().supportsFatherAndSubEdgeLabel()); + + // g.V("id").outE("label") + List list = init10Edges(); + Vertex person1 = list.get(0); + Vertex person2 = list.get(1); + Vertex person3 = list.get(2); + + List edges; + edges = graph().traversal().V(person1.id()) + .outE("transfer").toList(); + Assert.assertEquals(2, edges.size()); + + edges = graph().traversal().V(person1.id()) + .outE("transfer-1").toList(); + Assert.assertEquals(2, edges.size()); + + edges = graph().traversal().V(person1.id()) + .outE("transfer-2").toList(); + Assert.assertEquals(0, edges.size()); + + edges = graph().traversal().V(person1.id()) + .outE("transfer", "know").toList(); + Assert.assertEquals(2 + 1, edges.size()); + + edges = graph().traversal().V(person2.id()) + .outE("transfer-1").toList(); + Assert.assertEquals(2, edges.size()); + + edges = graph().traversal().V(person2.id()) + .outE("transfer").toList(); + Assert.assertEquals(5, edges.size()); + + edges = graph().traversal().V(person2.id()) + .outE("transfer-1").toList(); + Assert.assertEquals(2, edges.size()); + + edges = graph().traversal().V(person2.id()) + .outE("transfer-2").toList(); + Assert.assertEquals(3, edges.size()); + } + + @Test + public void testQueryParentAndSubEdgesWithVertexOutAndConditions() { + Assume.assumeTrue("Not support father and sub edge label", + this.storeFeatures().supportsFatherAndSubEdgeLabel()); + + // g.V("id").outE("label").has("amount",10.00) + List list = init10Edges(); + Vertex person1 = list.get(0); + Vertex person2 = list.get(1); + Vertex person3 = list.get(2); + + List edges; + edges = graph().traversal().V(person1.id()) + .outE("transfer") + .has("amount", 10.00).toList(); + Assert.assertEquals(1, edges.size()); + + edges = graph().traversal().V(person1.id()) + .outE("transfer-1") + .has("amount", 10.00).toList(); + Assert.assertEquals(1, edges.size()); + } + + @Test + public void testQueryParentAndSubEdgesWithVertexOutAndSortKeys() { + Assume.assumeTrue("Not support father and sub edge label", + this.storeFeatures().supportsFatherAndSubEdgeLabel()); + + // g.V("id").outE("label").has("sortKeys","value") + List list = init10Edges(); + Vertex person1 = list.get(0); + Vertex person2 = list.get(1); + Vertex person3 = list.get(2); + + int transferEdges = graph().traversal().V(person2.id()) + .outE("transfer") + .has("time", "2022-1-1").toList().size(); + Assert.assertEquals(2, transferEdges); + + int transfer1Edges = graph().traversal().V(person2.id()) + .outE("transfer-1") + .has("time", "2022-1-1").toList().size(); + int transfer2Edges = graph().traversal().V(person2.id()) + .outE("transfer-2") + .has("time", "2022-1-1").toList().size(); + Assert.assertEquals(transferEdges, transfer1Edges + transfer2Edges); + } + + @Test + public void testQueryParentAndSubEdgesWithVertexOutAndSortKeysAndConditions() { + Assume.assumeTrue("Not support father and sub edge label", + this.storeFeatures().supportsFatherAndSubEdgeLabel()); + + // g.V("id").outE("label").has("sortKeys","value").has(K,V) + List list = init10Edges(); + Vertex person1 = list.get(0); + Vertex person2 = list.get(1); + Vertex person3 = list.get(2); + + int transferEdges = graph().traversal().V(person2.id()) + .outE("transfer") + .has("time", "2022-1-1") + .has("amount", 10.00) + .toList().size(); + Assert.assertEquals(2, transferEdges); + + int transfer1Edges = graph().traversal().V(person2.id()) + .outE("transfer-1") + .has("time", "2022-1-1") + .has("amount", 10.00) + .toList().size(); + int transfer2Edges = graph().traversal().V(person2.id()) + .outE("transfer-2") + .has("time", "2022-1-1") + .has("amount", 10.00) + .toList().size(); + Assert.assertEquals(transferEdges, transfer1Edges + transfer2Edges); + } +} diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java index 1a6738a8e3..212ccc0588 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/TaskCoreTest.java @@ -348,13 +348,13 @@ public void testGremlinJobWithSerializedResults() throws TimeoutException { String expected = String.format("[{\"labels\":[[],[],[]],\"objects\":[" + "{\"id\":1,\"label\":\"char\",\"type\":\"vertex\"," + "\"properties\":{\"name\":\"A\"}}," + - "{\"id\":\"L1>%s>>L2\",\"label\":\"next\"," + + "{\"id\":\"L1>%s>%s>>L2\",\"label\":\"next\"," + "\"type\":\"edge\",\"outV\":1," + "\"outVLabel\":\"char\",\"inV\":2,\"" + "inVLabel\":\"char\",\"properties\":{\"name\":\"ab\"}}," + "{\"id\":2,\"label\":\"char\",\"type\":\"vertex\"," + "\"properties\":{\"name\":\"B\"}}" + - "]}]", edgeLabelId); + "]}]", edgeLabelId, edgeLabelId); Assert.assertEquals(expected, task.result()); script = "g.V(1).out().out().path()"; @@ -384,14 +384,14 @@ public void testGremlinJobWithSerializedResults() throws TimeoutException { expected = String.format("[[{\"key\":{\"id\":1,\"label\":\"char\",\"type\":\"vertex\"," + "\"properties\":{\"name\":\"A\"}}," + "\"value\":[" + - "{\"key\":{\"id\":\"L1>%s>>L2\",\"label\":\"next\"," + + "{\"key\":{\"id\":\"L1>%s>%s>>L2\",\"label\":\"next\"," + "\"type\":\"edge\",\"outV\":1," + "\"outVLabel\":\"char\",\"inV\":2,\"inVLabel\":\"char\"," + "\"properties\":{\"name\":\"ab\"}}," + "\"value\":[{\"key\":{\"id\":2,\"label\":\"char\"," + "\"type\":\"vertex\"," + "\"properties\":{\"name\":\"B\"}},\"value\":[]}]}]}]]", - edgeLabelId); + edgeLabelId, edgeLabelId); Assert.assertEquals(expected, task.result()); script = "g.V(1).out().out().tree()"; @@ -552,7 +552,7 @@ public void testGremlinJobAndCancel() throws TimeoutException { HugeTask task = runGremlinJob("Thread.sleep(1000 * 10);"); - sleepAWhile(); + sleepAWhile(200 * 6); task = scheduler.task(task.id()); scheduler.cancel(task); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexCoreTest.java index c9a83ddc15..a329de3afb 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexCoreTest.java @@ -44,6 +44,7 @@ import org.apache.hugegraph.backend.query.Condition; import org.apache.hugegraph.backend.query.ConditionQuery; import org.apache.hugegraph.backend.query.Query; +import org.apache.hugegraph.backend.serializer.BytesBuffer; import org.apache.hugegraph.backend.store.BackendTable; import org.apache.hugegraph.backend.store.Shard; import org.apache.hugegraph.backend.tx.GraphTransaction; @@ -1039,10 +1040,10 @@ public void testAddVertexWithCustomizeStringIdStrategyWithoutValidId() { "name", "marko", "age", 18, "city", "Beijing"); }); - // Expect id length <= 128 + // Expect id length <= BytesBuffer.ID_LEN_MAX Assert.assertThrows(IllegalArgumentException.class, () -> { - String largeId = new String(new byte[128]) + "."; - assert largeId.length() == 129; + String largeId = new String(new byte[BytesBuffer.ID_LEN_MAX]) + "."; + assert largeId.length() == BytesBuffer.ID_LEN_MAX + 1; graph.addVertex(T.label, "programmer", T.id, largeId, "name", "marko", "age", 18, "city", "Beijing"); }); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/FakeObjects.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/FakeObjects.java index 67f5c3781f..9dabd72a3a 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/FakeObjects.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/FakeObjects.java @@ -156,7 +156,7 @@ public HugeEdge newEdge(long sourceVertexId, long targetVertexId) { target.addProperty(age, 20); target.addProperty(city, "Shanghai"); - Id id = EdgeId.parse("L123456>1>>L987654"); + Id id = EdgeId.parse("L123456>1>1>>L987654"); HugeEdge edge = new HugeEdge(this.graph(), id, el); Whitebox.setInternalState(edge, "sourceVertex", source); @@ -199,7 +199,7 @@ public HugeEdge newEdge(String sourceVertexId, String targetVertexId) { target.addProperty(age, 20); target.addProperty(city, "Shanghai"); - Id id = EdgeId.parse("L123456>1>>L987654"); + Id id = EdgeId.parse("L123456>1>1>>L987654"); HugeEdge edge = new HugeEdge(this.graph(), id, el); Whitebox.setInternalState(edge, "sourceVertex", source); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheTest.java index 63837c8aab..d9bd4cf953 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/cache/CacheTest.java @@ -139,6 +139,7 @@ protected void checkNotInCache(Cache cache, Id id) { public static class OffheapCacheTest extends CacheTest { private static final long ENTRY_SIZE = 40L; + private static final int SEGMENTS = 4; private final HugeGraph graph = Mockito.mock(HugeGraph.class); @Override @@ -148,7 +149,7 @@ protected Cache newCache() { @Override protected Cache newCache(long capacity) { - return new OffheapCache(this.graph(), capacity, ENTRY_SIZE); + return new OffheapCache(this.graph(), capacity, ENTRY_SIZE, SEGMENTS); } @Override @@ -325,7 +326,7 @@ public void testUpdateAndGetWithDataType() { @Test public void testUpdateAndGetWithSameSizeAndCapacity() { - int limit = 40; + int limit = 1000; Cache cache = newCache(limit); Map map = new LimitMap(limit); @@ -451,7 +452,7 @@ public void testSize() { @Test public void testSizeWithReachCapacity() { - int limit = 20; + int limit = 1000; Cache cache = newCache(limit); Map map = new LimitMap(limit); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/EdgeIdTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/EdgeIdTest.java index 47a6428080..0c917832f8 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/EdgeIdTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/EdgeIdTest.java @@ -46,12 +46,15 @@ public void teardown() { @Test public void testEdgeIdEqual() { EdgeId edgeId1 = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:josh")); EdgeId edgeId2 = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:josh")); EdgeId edgeId3 = new EdgeId(IdGenerator.of("1:josh"), Directions.IN, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:marko")); Assert.assertTrue(edgeId1.equals(edgeId2)); @@ -63,12 +66,15 @@ public void testEdgeIdEqual() { @Test public void testEdgeIdEqualWithDirection() { EdgeId edgeId1 = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:josh"), true); EdgeId edgeId2 = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:josh"), true); EdgeId edgeId3 = new EdgeId(IdGenerator.of("1:josh"), Directions.IN, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:marko"), true); Assert.assertTrue(edgeId1.equals(edgeId2)); @@ -80,17 +86,20 @@ public void testEdgeIdEqualWithDirection() { @Test public void testCollectionContainsEdgeId() { EdgeId edgeId1 = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:josh")); Set edgeIds = ImmutableSet.of(edgeId1); Assert.assertTrue(edgeIds.contains(edgeId1)); EdgeId edgeId2 = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:josh")); Assert.assertTrue(edgeIds.contains(edgeId2)); EdgeId edgeId3 = new EdgeId(IdGenerator.of("1:josh"), Directions.IN, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:marko")); Assert.assertTrue(edgeIds.contains(edgeId3)); @@ -99,17 +108,20 @@ public void testCollectionContainsEdgeId() { @Test public void testCollectionContainsEdgeIdWithDirection() { EdgeId edgeId1 = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:josh"), true); Set edgeIds = ImmutableSet.of(edgeId1); Assert.assertTrue(edgeIds.contains(edgeId1)); EdgeId edgeId2 = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:josh"), true); Assert.assertTrue(edgeIds.contains(edgeId2)); EdgeId edgeId3 = new EdgeId(IdGenerator.of("1:josh"), Directions.IN, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:marko"), true); Assert.assertFalse(edgeIds.contains(edgeId3)); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdUtilTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdUtilTest.java index fa582322ab..473dc61891 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdUtilTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/id/IdUtilTest.java @@ -43,13 +43,13 @@ public void testWriteReadString() { Assert.assertEquals("U" + uuid, IdUtil.writeString(id)); Assert.assertEquals(id, IdUtil.readString("U" + uuid)); - id = EdgeId.parse("S1>2>3>L4"); - Assert.assertEquals("ES1>2>3>L4", IdUtil.writeString(id)); - Assert.assertEquals(id, IdUtil.readString("ES1>2>3>L4")); + id = EdgeId.parse("S1>2>3>4>L6"); + Assert.assertEquals("ES1>2>3>4>L6", IdUtil.writeString(id)); + Assert.assertEquals(id, IdUtil.readString("ES1>2>3>4>L6")); - id = EdgeId.parse("S1111>2222>3>L4444"); - Assert.assertEquals("ES1111>2222>3>L4444", IdUtil.writeString(id)); - Assert.assertEquals(id, IdUtil.readString("ES1111>2222>3>L4444")); + id = EdgeId.parse("S1111>2222>3>4>L6666"); + Assert.assertEquals("ES1111>2222>3>4>L6666", IdUtil.writeString(id)); + Assert.assertEquals(id, IdUtil.readString("ES1111>2222>3>4>L6666")); } @Test @@ -70,23 +70,23 @@ public void testWriteReadBinString() { Assert.assertEquals(bytes, IdUtil.writeBinString(id)); Assert.assertEquals(id, IdUtil.readBinString(bytes)); - id = EdgeId.parse("S1>2>3>L4"); - bytes = ByteBuffer.wrap(genBytes("7e803182080233000804")); + id = EdgeId.parse("S1>2>2>4>L6"); + bytes = ByteBuffer.wrap(genBytes("7e8031820802080234000806")); Assert.assertEquals(bytes, IdUtil.writeBinString(id)); Assert.assertEquals(id, IdUtil.readBinString(bytes)); - id = EdgeId.parse("S1111>2222>3>L4444"); - bytes = ByteBuffer.wrap(genBytes("7e8331313131821808ae330018115c")); + id = EdgeId.parse("S1111>2222>3>4>L6666"); + bytes = ByteBuffer.wrap(genBytes("7e8331313131821808ae08033400181a0a")); Assert.assertEquals(bytes, IdUtil.writeBinString(id)); Assert.assertEquals(id, IdUtil.readBinString(bytes)); - id = EdgeId.parse("L11111111>2222>3>L44444444"); - bytes = ByteBuffer.wrap(genBytes("7e28a98ac7821808ae33002aa62b1c")); + id = EdgeId.parse("L11111111>2222>3>4>L66666666"); + bytes = ByteBuffer.wrap(genBytes("7e28a98ac7821808ae080334002bf940aa")); Assert.assertEquals(bytes, IdUtil.writeBinString(id)); Assert.assertEquals(id, IdUtil.readBinString(bytes)); - id = EdgeId.parse("L-1111>2222>33>L4444"); - bytes = ByteBuffer.wrap(genBytes("7e03a9821808ae33330018115c")); + id = EdgeId.parse("L-1111>2222>33>55>L7777"); + bytes = ByteBuffer.wrap(genBytes("7e03a9821808ae0821353500181e61")); Assert.assertEquals(bytes, IdUtil.writeBinString(id)); Assert.assertEquals(id, IdUtil.readBinString(bytes)); } @@ -106,25 +106,25 @@ public void testWriteReadStoredString() { Assert.assertEquals(uuid, IdUtil.writeStoredString(id)); Assert.assertEquals(id, IdUtil.readStoredString(uuid)); - id = EdgeId.parse("S1>2>3>L4"); - Assert.assertEquals("ES1>2>3>L4", IdUtil.writeStoredString(id)); - Assert.assertEquals(id, IdUtil.readStoredString("ES1>2>3>L4")); + id = EdgeId.parse("S1>2>3>4>L6"); + Assert.assertEquals("ES1>2>3>4>L6", IdUtil.writeStoredString(id)); + Assert.assertEquals(id, IdUtil.readStoredString("ES1>2>3>4>L6")); - id = EdgeId.parse("S1111>2222>3>L4444"); - Assert.assertEquals("ES1111>Yj>3>L15S", IdUtil.writeStoredString(id)); - Assert.assertEquals(id, IdUtil.readStoredString("ES1111>Yj>3>L15S")); + id = EdgeId.parse("S1111>2222>3>6>L4444"); + Assert.assertEquals("ES1111>Yj>3>6>L15S", IdUtil.writeStoredString(id)); + Assert.assertEquals(id, IdUtil.readStoredString("ES1111>Yj>3>6>L15S")); - id = EdgeId.parse("L1111>2222>3>L4444"); - Assert.assertEquals("ELHN>Yj>3>L15S", IdUtil.writeStoredString(id)); - Assert.assertEquals(id, IdUtil.readStoredString("ELHN>Yj>3>L15S")); + id = EdgeId.parse("L1111>2222>3>6>L4444"); + Assert.assertEquals("ELHN>Yj>3>6>L15S", IdUtil.writeStoredString(id)); + Assert.assertEquals(id, IdUtil.readStoredString("ELHN>Yj>3>6>L15S")); - id = EdgeId.parse("L11111111>2222>3>L44444444"); - String eid = "ELfOg7>Yj>3>L2eYhS"; + id = EdgeId.parse("L11111111>2222>3>6>L44444444"); + String eid = "ELfOg7>Yj>3>6>L2eYhS"; Assert.assertEquals(eid, IdUtil.writeStoredString(id)); Assert.assertEquals(id, IdUtil.readStoredString(eid)); - id = EdgeId.parse("L-1111>2222>33>L4444"); - eid = "EL-HN>Yj>33>L15S"; + id = EdgeId.parse("L-1111>2222>6>7>L4444"); + eid = "EL-HN>Yj>6>7>L15S"; Assert.assertEquals(eid, IdUtil.writeStoredString(id)); Assert.assertEquals(id, IdUtil.readStoredString(eid)); } @@ -154,4 +154,22 @@ private byte[] genBytes(String string) { } return bytes; } + + /** + * Converts a byte array to a hexadecimal string. + * + * @param bytes the byte array to convert + * @return the hexadecimal string representation of the byte array + */ + private String bytesToHex(byte[] bytes) { + StringBuilder hexString = new StringBuilder(); + for (byte b : bytes) { + String hex = Integer.toHexString(0xFF & b); + if (hex.length() == 1) { + hexString.append('0'); // pad with leading zero if needed + } + hexString.append(hex); + } + return hexString.toString(); + } } diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BytesBufferTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BytesBufferTest.java index 9072652908..fb25a5b255 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BytesBufferTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BytesBufferTest.java @@ -96,29 +96,35 @@ public void testStringId() { @Test public void testStringIdWithBigSize() { Id id = IdGenerator.of(genString(127)); - byte[] bytes = genBytes(128); - bytes[0] = (byte) 0xfe; + byte[] bytes = genBytes(129); + bytes[0] = (byte) 0xc0; + bytes[1] = (byte) 0x7e; Assert.assertArrayEquals(bytes, BytesBuffer.allocate(0) .writeId(id).bytes()); Assert.assertEquals(id, BytesBuffer.wrap(bytes).readId()); id = IdGenerator.of(genString(128)); - bytes = genBytes(129); - bytes[0] = (byte) 0xff; + bytes = genBytes(130); + bytes[0] = (byte) 0xc0; + bytes[1] = (byte) 0x7f; Assert.assertArrayEquals(bytes, BytesBuffer.allocate(0) .writeId(id).bytes()); Assert.assertEquals(id, BytesBuffer.wrap(bytes).readId()); Assert.assertThrows(IllegalArgumentException.class, () -> { - BytesBuffer.allocate(0).writeId(IdGenerator.of(genString(129))); + BytesBuffer.allocate(0).writeId(IdGenerator.of(genString(BytesBuffer.ID_LEN_MAX + 1))); }, e -> { - Assert.assertContains("Id max length is 128, but got 129", + Assert.assertContains(String.format("Big id max length is %s, but got %s", + BytesBuffer.ID_LEN_MAX, + BytesBuffer.ID_LEN_MAX + 1), e.getMessage()); }); Assert.assertThrows(IllegalArgumentException.class, () -> { - BytesBuffer.allocate(0).writeId(IdGenerator.of(genString(130))); + BytesBuffer.allocate(0).writeId(IdGenerator.of(genString(BytesBuffer.ID_LEN_MAX + 2))); }, e -> { - Assert.assertContains("Id max length is 128, but got 130", + Assert.assertContains(String.format("Big id max length is %s, but got %s", + BytesBuffer.ID_LEN_MAX, + BytesBuffer.ID_LEN_MAX + 2), e.getMessage()); }); } @@ -127,33 +133,34 @@ public void testStringIdWithBigSize() { public void testStringBigId() { Id id = IdGenerator.of(genString(128)); byte[] bytes = genBytes(130); - bytes[0] = (byte) 0x80; + bytes[0] = (byte) 0xc0; bytes[1] = (byte) 0x7f; Assert.assertArrayEquals(bytes, BytesBuffer.allocate(0) - .writeId(id, true).bytes()); - Assert.assertEquals(id, BytesBuffer.wrap(bytes).readId(true)); + .writeId(id).bytes()); + Assert.assertEquals(id, BytesBuffer.wrap(bytes).readId()); - id = IdGenerator.of(genString(32512)); - bytes = genBytes(32514); - bytes[0] = (byte) 0xfe; - bytes[1] = (byte) 0xff; + id = IdGenerator.of(genString(BytesBuffer.ID_LEN_MAX - 1)); + bytes = genBytes(BytesBuffer.ID_LEN_MAX + 1); + bytes[0] = (byte) 0xff; + bytes[1] = (byte) 0xfe; Assert.assertArrayEquals(bytes, BytesBuffer.allocate(0) - .writeId(id, true).bytes()); - Assert.assertEquals(id, BytesBuffer.wrap(bytes).readId(true)); + .writeId(id).bytes()); + Assert.assertEquals(id, BytesBuffer.wrap(bytes).readId()); - id = IdGenerator.of(genString(32768)); - bytes = genBytes(32770); + id = IdGenerator.of(genString(BytesBuffer.ID_LEN_MAX)); + bytes = genBytes(BytesBuffer.ID_LEN_MAX + 2); bytes[0] = (byte) 0xff; bytes[1] = (byte) 0xff; Assert.assertArrayEquals(bytes, BytesBuffer.allocate(0) - .writeId(id, true).bytes()); - Assert.assertEquals(id, BytesBuffer.wrap(bytes).readId(true)); + .writeId(id).bytes()); + Assert.assertEquals(id, BytesBuffer.wrap(bytes).readId()); Assert.assertThrows(IllegalArgumentException.class, () -> { - BytesBuffer.allocate(0).writeId(IdGenerator.of(genString(32769)), - true); + BytesBuffer.allocate(0).writeId(IdGenerator.of(genString(BytesBuffer.ID_LEN_MAX + 1))); }, e -> { - Assert.assertContains("Big id max length is 32768, but got 32769", + Assert.assertContains(String.format("Big id max length is %s, but got %s", + BytesBuffer.ID_LEN_MAX, + BytesBuffer.ID_LEN_MAX + 1), e.getMessage()); }); } diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/JsonUtilTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/JsonUtilTest.java index b311651953..6c5159d377 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/JsonUtilTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/util/JsonUtilTest.java @@ -18,10 +18,13 @@ package org.apache.hugegraph.unit.util; import java.util.Arrays; +import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.UUID; +import org.apache.commons.lang3.tuple.Pair; import org.apache.hugegraph.backend.id.EdgeId; import org.apache.hugegraph.backend.id.Id; import org.apache.hugegraph.backend.id.IdGenerator; @@ -82,10 +85,11 @@ public void testSerializeUuidId() { @Test public void testSerializeEdgeId() { Id id = new EdgeId(IdGenerator.of("1:marko"), Directions.OUT, + IdGenerator.of(1), IdGenerator.of(1), "", IdGenerator.of("1:josh")); String json = JsonUtil.toJson(id); - Assert.assertEquals("\"S1:marko>1>>S1:josh\"", json); + Assert.assertEquals("\"S1:marko>1>1>>S1:josh\"", json); } @Test @@ -167,11 +171,13 @@ public void testSerializeEdgeLabel() { Mockito.when(fakeObject.graph().vertexLabel(vl.id())).thenReturn(vl); Mockito.when(fakeObject.graph().mapPkId2Name(el.properties())) .thenReturn(Arrays.asList(date.name(), weight.name())); + Mockito.when(fakeObject.graph().mapPairId2Name(el.links())) + .thenReturn(Collections.singleton(Pair.of(name.name(), name.name()))); String json = JsonUtil.toJson(el); Assert.assertEquals("{\"id\":1,\"name\":\"knows\"," + - "\"source_label\":\"person\"," + - "\"target_label\":\"person\"," + + "\"edgelabel_type\":\"NORMAL\"," + + "\"links\":[{\"name\":\"name\"}]," + "\"frequency\":\"SINGLE\",\"sort_keys\":[]," + "\"nullable_keys\":[],\"index_labels\":[]," + "\"properties\":[\"date\",\"weight\"]," + @@ -277,7 +283,7 @@ public void testSerializeEdge() { HugeVertex target = new HugeVertex(fakeObject.graph(), IdGenerator.of(987654), vl); - Id id = EdgeId.parse("L123456>1>>L987654"); + Id id = EdgeId.parse("L123456>1>1>>L987654"); HugeEdge edge = new HugeEdge(fakeObject.graph(), id, el); Whitebox.setInternalState(edge, "sourceVertex", source); Whitebox.setInternalState(edge, "targetVertex", target); @@ -291,7 +297,7 @@ public void testSerializeEdge() { Whitebox.setInternalState(edge, "properties", properties); String json = JsonUtil.toJson(edge); - Assert.assertEquals("{\"id\":\"L123456>1>>L987654\"," + + Assert.assertEquals("{\"id\":\"L123456>1>1>>L987654\"," + "\"label\":\"knows\",\"type\":\"edge\"," + "\"outV\":123456,\"outVLabel\":\"person\"," + "\"inV\":987654,\"inVLabel\":\"person\"," + diff --git a/hugegraph-store/Dockerfile b/hugegraph-store/Dockerfile index 042ceef42f..b677da2f6b 100644 --- a/hugegraph-store/Dockerfile +++ b/hugegraph-store/Dockerfile @@ -23,7 +23,7 @@ COPY . /pkg WORKDIR /pkg ARG MAVEN_ARGS -RUN mvn package $MAVEN_ARGS -e -B -ntp -DskipTests -Dmaven.javadoc.skip=true && pwd && ls -l && rm \ +RUN mvn package $MAVEN_ARGS -e -B -ntp -Dmaven.test.skip=true -Dmaven.javadoc.skip=true && pwd && ls -l && rm \ ./hugegraph-server/*.tar.gz && rm ./hugegraph-pd/*.tar.gz && rm ./hugegraph-store/*.tar.gz # 2nd stage: runtime env diff --git a/hugegraph-store/hg-store-cli/pom.xml b/hugegraph-store/hg-store-cli/pom.xml index 8757a09c8f..84de815696 100644 --- a/hugegraph-store/hg-store-cli/pom.xml +++ b/hugegraph-store/hg-store-cli/pom.xml @@ -56,6 +56,10 @@ hg-pd-client ${revision} + + org.projectlombok + lombok + diff --git a/hugegraph-store/hg-store-client/pom.xml b/hugegraph-store/hg-store-client/pom.xml index afa97fa0c2..736bc36790 100644 --- a/hugegraph-store/hg-store-client/pom.xml +++ b/hugegraph-store/hg-store-client/pom.xml @@ -32,7 +32,6 @@ true - 1.18.20 @@ -60,7 +59,6 @@ org.projectlombok lombok - ${lombok.version} org.apache.logging.log4j diff --git a/hugegraph-store/hg-store-core/pom.xml b/hugegraph-store/hg-store-core/pom.xml index 60a0954ac9..e59298efa8 100644 --- a/hugegraph-store/hg-store-core/pom.xml +++ b/hugegraph-store/hg-store-core/pom.xml @@ -34,7 +34,6 @@ org.projectlombok lombok - 1.18.24 org.apache.logging.log4j @@ -55,7 +54,6 @@ org.rocksdb rocksdbjni - diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/PartitionEngine.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/PartitionEngine.java index 11538478cc..ee65162f7c 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/PartitionEngine.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/PartitionEngine.java @@ -249,6 +249,7 @@ public LogStorage createLogStorage(final String uri, final RaftOptions raftOptio raftOptions.setMaxReplicatorInflightMsgs( options.getRaftOptions().getMaxReplicatorInflightMsgs()); raftOptions.setMaxByteCountPerRpc(1024 * 1024); + raftOptions.setMaxBodySize(options.getRaftOptions().getMaxBodySize()); nodeOptions.setEnableMetrics(true); final PeerId serverId = JRaftUtils.getPeerId(options.getRaftAddress()); diff --git a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/options/HgStoreEngineOptions.java b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/options/HgStoreEngineOptions.java index 3b3ff9bc78..c315d3440e 100644 --- a/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/options/HgStoreEngineOptions.java +++ b/hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/options/HgStoreEngineOptions.java @@ -98,7 +98,11 @@ public static class RaftOptions { /** * The maximum number of entries in AppendEntriesRequest */ - private final int maxEntriesSize = 256; + private int maxEntriesSize = 256; + /** + * The maximum byte size of AppendEntriesRequest + */ + private int maxBodySize = 512 * 1024; /** * Raft cluster data backlog occurs, rate limiting wait time in milliseconds. **/ diff --git a/hugegraph-store/hg-store-dist/src/assembly/static/bin/start-hugegraph-store.sh b/hugegraph-store/hg-store-dist/src/assembly/static/bin/start-hugegraph-store.sh index b363b7ab45..d8b965a07d 100644 --- a/hugegraph-store/hg-store-dist/src/assembly/static/bin/start-hugegraph-store.sh +++ b/hugegraph-store/hg-store-dist/src/assembly/static/bin/start-hugegraph-store.sh @@ -74,13 +74,13 @@ export FILE_LIMITN=1024 function check_evn_limit() { local limit_check=$(ulimit -n) - if [ ${limit_check} -lt ${FILE_LIMITN} ]; then - echo -e "${BASH_SOURCE[0]##*/}:${LINENO}:\E[1;32m ulimit -n 可以打开的最大文件描述符数太少,需要(${FILE_LIMITN})!! \E[0m" + if [[ ${limit_check} != "unlimited" && ${limit_check} -lt ${FILE_LIMITN} ]]; then + echo -e "${BASH_SOURCE[0]##*/}:${LINENO}:\E[1;32m ulimit -n can open too few maximum file descriptors, need (${FILE_LIMITN})!! \E[0m" return 1 fi limit_check=$(ulimit -u) - if [ ${limit_check} -lt ${PROC_LIMITN} ]; then - echo -e "${BASH_SOURCE[0]##*/}:${LINENO}:\E[1;32m ulimit -u 用户最大可用的进程数太少,需要(${PROC_LIMITN})!! \E[0m" + if [[ ${limit_check} != "unlimited" && ${limit_check} -lt ${PROC_LIMITN} ]]; then + echo -e "${BASH_SOURCE[0]##*/}:${LINENO}:\E[1;32m ulimit -u too few available processes for the user, need (${PROC_LIMITN})!! \E[0m" return 2 fi return 0 @@ -144,23 +144,29 @@ if [ "$JAVA_OPTIONS" = "" ]; then >> ${OUTPUT} exit 1 fi - JAVA_OPTIONS="-Xms${MIN_MEM}m -Xmx${XMX}m -XX:MetaspaceSize=256M -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGS} ${USER_OPTION} " + JAVA_OPTIONS="-Xms${MIN_MEM}m -Xmx${XMX}m -XX:MetaspaceSize=256M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGS} ${USER_OPTION} " # JAVA_OPTIONS="-Xms${MIN_MEM}m -Xmx${XMX}m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGS} ${USER_OPTION}" # Rolling out detailed GC logs - JAVA_OPTIONS="${JAVA_OPTIONS} -Xlog:gc=info:file=./logs/gc.log:tags,uptime,level:filecount=3,filesize=100m " + JAVA_OPTIONS="${JAVA_OPTIONS} -Xlog:gc=info:file=./logs/gc.log:time,uptime,level,tags:filecount=3,filesize=100m" fi # Using G1GC as the default garbage collector (Recommended for large memory machines) case "$GC_OPTION" in - g1) + "") echo "Using G1GC as the default garbage collector" - JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+UseG1GC -XX:+ParallelRefProcEnabled \ + JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+ParallelRefProcEnabled \ -XX:InitiatingHeapOccupancyPercent=50 -XX:G1RSetUpdatingPauseTimePercent=5" ;; - "") ;; + zgc|ZGC) + echo "Using ZGC as the default garbage collector (Only support Java 11+)" + JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+UseZGC -XX:+UnlockExperimentalVMOptions \ + -XX:ConcGCThreads=2 -XX:ParallelGCThreads=6 \ + -XX:ZCollectionInterval=120 -XX:ZAllocationSpikeTolerance=5 \ + -XX:+UnlockDiagnosticVMOptions -XX:-ZProactive" + ;; *) - echo "Unrecognized gc option: '$GC_OPTION', only support 'g1' now" >> ${OUTPUT} + echo "Unrecognized gc option: '$GC_OPTION', default use g1, options only support 'ZGC' now" >> ${OUTPUT} exit 1 esac diff --git a/hugegraph-store/hg-store-dist/src/assembly/static/conf/application-pd.yml b/hugegraph-store/hg-store-dist/src/assembly/static/conf/application-pd.yml index df535953fc..0315c4b4fe 100644 --- a/hugegraph-store/hg-store-dist/src/assembly/static/conf/application-pd.yml +++ b/hugegraph-store/hg-store-dist/src/assembly/static/conf/application-pd.yml @@ -26,9 +26,9 @@ management: include: "*" rocksdb: - # rocksdb 使用的总内存大小,达到该值强制写盘 + # rocksdb total memory usage, force flush to disk when reaching this value total_memory_size: 32000000000 - # rocksdb 使用的 memtable 大小 + # memtable size used by rocksdb write_buffer_size: 32000000 - # 对于每个 rocksdb 来说,memtable 个数达到该值进行写盘 + # For each rocksdb, the number of memtables reaches this value for writing to disk. min_write_buffer_number_to_merge: 16 diff --git a/hugegraph-store/hg-store-dist/src/assembly/static/conf/application.yml b/hugegraph-store/hg-store-dist/src/assembly/static/conf/application.yml index 4ca3d34dd6..8e2b8d4f74 100644 --- a/hugegraph-store/hg-store-dist/src/assembly/static/conf/application.yml +++ b/hugegraph-store/hg-store-dist/src/assembly/static/conf/application.yml @@ -16,7 +16,7 @@ # pdserver: - # pd 服务地址,多个 pd 地址用逗号分割 + # PD service address, multiple PD addresses separated by commas address: localhost:8686 management: @@ -30,24 +30,24 @@ management: include: "*" grpc: - # grpc 的服务地址 + # grpc service address host: 127.0.0.1 port: 8500 netty-server: max-inbound-message-size: 1000MB raft: - # raft 缓存队列大小 + # raft cache queue size disruptorBufferSize: 1024 address: 127.0.0.1:8510 max-log-file-size: 600000000000 - # 快照生成时间间隔,单位秒 + # Snapshot generation interval, in seconds snapshotInterval: 1800 server: - # rest 服务地址 + # rest service address port: 8520 app: - # 存储路径,支持多个路径,逗号分割 + # Storage path, support multiple paths, separated by commas data-path: ./storage #raft-path: ./storage diff --git a/hugegraph-store/hg-store-grpc/pom.xml b/hugegraph-store/hg-store-grpc/pom.xml index 3e7cc6adda..75f4594a0d 100644 --- a/hugegraph-store/hg-store-grpc/pom.xml +++ b/hugegraph-store/hg-store-grpc/pom.xml @@ -91,23 +91,23 @@ io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} - + ${project.basedir}/src/main/proto - + ${project.basedir}/src/main/java - + false - + - + generate-sources - + compile - + compile-custom diff --git a/hugegraph-store/hg-store-grpc/src/main/proto/graphpb.proto b/hugegraph-store/hg-store-grpc/src/main/proto/graphpb.proto index a245002f85..6e9d16d2eb 100644 --- a/hugegraph-store/hg-store-grpc/src/main/proto/graphpb.proto +++ b/hugegraph-store/hg-store-grpc/src/main/proto/graphpb.proto @@ -30,20 +30,20 @@ message ScanPartitionRequest{ SCAN_VERTEX = 1; SCAN_EDGE = 2; } - // 请求参数 + // Request parameters message Request{ ScanType scan_type = 1; string graph_name = 2; uint32 partition_id = 3; uint32 start_code = 4; uint32 end_code = 5; - // 过滤条件 + // Filter conditions string condition = 6; string table = 7; int64 limit = 8; int32 boundary = 9; bytes position = 10; - // 返回条件 + // Return condition repeated int64 properties = 11; } @@ -54,14 +54,14 @@ message ScanPartitionRequest{ RequestHeader header = 1; oneof request { Request scan_request = 2; - // 每消费一个数据包,通知服务端一次,返回消息序号 + // Each time a data packet is consumed, notify the server once, return the message sequence number Reply reply_request = 4; } } message ScanResponse{ ResponseHeader header = 1; - // 消息序号 + // Message Sequence Number int32 seq_no = 2; repeated Vertex vertex = 3; repeated Edge edge = 4; @@ -74,19 +74,19 @@ message Property{ } message Vertex{ - int64 label = 1; // 点类型 - Variant id = 2; // 点ID - repeated Property properties = 3; //点属性 + int64 label = 1; // Point type + Variant id = 2; // Point ID + repeated Property properties = 3; // Point properties } message Edge{ - int64 label = 1; // 边类型 + int64 label = 1; // Edge type int64 sourceLabel = 2; int64 targetLabel = 3; - Variant source_id = 4; // 源点ID - Variant target_id = 5; // 目标点ID + Variant source_id = 4; // Source point ID + Variant target_id = 5; // Target point ID - repeated Property properties = 6; //边属性 + repeated Property properties = 6; // Edge properties } message Variant { @@ -116,7 +116,7 @@ enum VariantType { message RequestHeader { - // 发送者 ID. + // Sender ID. uint64 sender_id = 2; } diff --git a/hugegraph-store/hg-store-grpc/src/main/proto/store_common.proto b/hugegraph-store/hg-store-grpc/src/main/proto/store_common.proto index fc9934dec4..bc45670198 100644 --- a/hugegraph-store/hg-store-grpc/src/main/proto/store_common.proto +++ b/hugegraph-store/hg-store-grpc/src/main/proto/store_common.proto @@ -82,10 +82,10 @@ enum ScanMethod { } enum ScanOrderType{ - // 批量接口下,返回顺序的要求 - ORDER_NONE = 0; // 允许无序 - ORDER_WITHIN_VERTEX = 1; // 一个点内的边不会被打断,单不同点之间为无序 - ORDER_STRICT = 2; // 保证原始的输入点顺序 + // Under batch interface, the requirement for return order + ORDER_NONE = 0; // Allow unordered + ORDER_WITHIN_VERTEX = 1; // Edges within a vertex will not be broken, but the order between different vertices is unordered. + ORDER_STRICT = 2; // Ensure the original input point order } enum OpType { diff --git a/hugegraph-store/hg-store-grpc/src/main/proto/store_session.proto b/hugegraph-store/hg-store-grpc/src/main/proto/store_session.proto index b659645a63..e9cb940881 100644 --- a/hugegraph-store/hg-store-grpc/src/main/proto/store_session.proto +++ b/hugegraph-store/hg-store-grpc/src/main/proto/store_session.proto @@ -122,11 +122,11 @@ message PartitionLeader { enum PartitionFaultType{ PARTITION_FAULT_TYPE_UNKNOWN = 0; - // 当前不是Leader,返回Leader所在store + // Currently not the Leader, return the store where the Leader is located. PARTITION_FAULT_TYPE_NOT_LEADER = 1; - // 等待Leader超时,可能raft group创建失败 + // Wait for Leader timeout, possibly raft group creation failed PARTITION_FAULT_TYPE_WAIT_LEADER_TIMEOUT = 2; - // 分区不属于本机 + // Partition does not belong to this machine PARTITION_FAULT_TYPE_NOT_LOCAL = 3; } diff --git a/hugegraph-store/hg-store-node/pom.xml b/hugegraph-store/hg-store-node/pom.xml index cf0444584e..5406b1c8a4 100644 --- a/hugegraph-store/hg-store-node/pom.xml +++ b/hugegraph-store/hg-store-node/pom.xml @@ -83,7 +83,6 @@ org.projectlombok lombok - 1.18.24 org.springframework.boot diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppConfig.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppConfig.java index 6c561f4c02..674a7fe417 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppConfig.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppConfig.java @@ -49,14 +49,14 @@ public class AppConfig { @Value("${server.port}") private int restPort; - //内置pd模式,用于单机部署 + // Built-in pd mode, for standalone deployment @Value("${app.data-path: store}") private String dataPath; @Value("${app.raft-path:}") private String raftPath; - //内置pd模式,用于单机部署 + // Built-in pd mode, for standalone deployment @Value("${app.fake-pd: false}") private boolean fakePd; @Autowired @@ -97,7 +97,7 @@ public void init() { if (raft.getDisruptorBufferSize() == 0) { int size = (int) (totalMemory / 1000 / 1000 / 1000); size = (int) Math.pow(2, Math.round(Math.log(size) / Math.log(2))) * 32; - raft.setDisruptorBufferSize(size); // 每32M增加一个buffer + raft.setDisruptorBufferSize(size); // Increase one buffer every 32M } if (!rocksdb.containsKey("write_buffer_size") || @@ -172,16 +172,20 @@ public class Raft { private int snapshotInterval; @Value("${raft.disruptorBufferSize:0}") private int disruptorBufferSize; - @Value("${raft.max-log-file-size: 50000000000}") + @Value("${raft.max-log-file-size:50000000000}") private long maxLogFileSize; - @Value("${ave-logEntry-size-ratio : 0.95}") + @Value("${ave-logEntry-size-ratio:0.95}") private double aveLogEntrySizeRation; - @Value("${raft.useRocksDBSegmentLogStorage: true}") + @Value("${raft.useRocksDBSegmentLogStorage:true}") private boolean useRocksDBSegmentLogStorage; @Value("${raft.maxSegmentFileSize:67108864}") private int maxSegmentFileSize; @Value("${raft.maxReplicatorInflightMsgs:256}") private int maxReplicatorInflightMsgs; + @Value("${raft.maxEntriesSize:256}") + private int maxEntriesSize; + @Value("${raft.maxBodySize:524288}") + private int maxBodySize; } @@ -209,7 +213,7 @@ public class FakePdConfig { @Value("${fake-pd.store-list:''}") private String storeList; @Value("${fake-pd.peers-list:''}") - private String peersList; //fakePd模式下,raft集群初始配置 + private String peersList; // fakePd mode, raft cluster initial configuration @Value("${fake-pd.partition-count:3}") private int partitionCount; @Value("${fake-pd.shard-count:3}") diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppShutdownHook.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppShutdownHook.java index 4b02e4e498..b239a327a5 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppShutdownHook.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/AppShutdownHook.java @@ -43,7 +43,7 @@ public void run() { doSomethingForShutdown(); try { - mainThread.join(); //当收到停止信号时,等待mainThread的执行完成 + mainThread.join(); // Wait for mainThread to finish when a stop signal is received. } catch (InterruptedException ignored) { } System.out.println("Shut down complete."); diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/StoreNodeApplication.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/StoreNodeApplication.java index c74ccc3295..c793ed96f2 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/StoreNodeApplication.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/StoreNodeApplication.java @@ -39,7 +39,7 @@ public static void main(String[] args) { } public static void start() { - // 设置solt用到的日志位置 + // Set the log location for the slot usage String logPath = System.getProperty("logging.path"); if (StringUtils.isBlank(logPath)) { System.setProperty("logging.path", "logs"); diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/controller/HgTestController.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/controller/HgTestController.java index 8c23621b54..157c7dfdaf 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/controller/HgTestController.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/controller/HgTestController.java @@ -34,7 +34,7 @@ import lombok.extern.slf4j.Slf4j; /** - * 仅用于测试 + * For testing only */ @RestController @Slf4j @@ -75,7 +75,7 @@ public String deleteRaftNode(@PathVariable(value = "groupId") int groupId) { nodeService.getStoreEngine().destroyPartitionEngine(groupId, graphs); return "OK"; } else { - return "未找到分区"; + return "Partition not found"; } } diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/controller/PartitionAPI.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/controller/PartitionAPI.java index 9247f35c75..d55bcbf28a 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/controller/PartitionAPI.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/controller/PartitionAPI.java @@ -98,7 +98,7 @@ public Map getPartitions( String graphName = partitionEntry.getKey(); Partition pt = partitionEntry.getValue(); PartitionInfo partition = new PartitionInfo(pt); - // 此处为了打开所有的图,metric只返回已打开的图 + // Here to open all the graphs, metric only returns the opened graph businessHandler.getLatestSequenceNumber(graphName, pt.getId()); partition.setMetric( businessHandler.getPartitionMetric(graphName, pt.getId(), accurate)); @@ -142,7 +142,7 @@ public Raft getPartition(@PathVariable(value = "id") int id) { } /** - * 打印分区的所有key + * Print all keys in the partition */ @GetMapping(value = "/partition/dump/{id}", produces = MediaType.APPLICATION_JSON_VALUE) public Map dumpPartition(@PathVariable(value = "id") int id) throws @@ -171,7 +171,7 @@ public Map dumpPartition(@PathVariable(value = "id") int id) thr } /** - * 打印分区的所有key + * Print all keys in the partition */ @GetMapping(value = "/partition/clean/{id}", produces = MediaType.APPLICATION_JSON_VALUE) public Map cleanPartition(@PathVariable(value = "id") int id) throws @@ -196,7 +196,7 @@ public Map arthasstart( ArthasAgent.attach(configMap); // DashResponse retPose = new DashResponse(); List ret = new ArrayList<>(); - ret.add("Arthas 启动成功"); + ret.add("Arthas started successfully"); return okMap("arthasstart", ret); } diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/BatchGrpcClosure.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/BatchGrpcClosure.java index d4ee59cfaa..14c0926787 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/BatchGrpcClosure.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/BatchGrpcClosure.java @@ -44,7 +44,7 @@ import lombok.extern.slf4j.Slf4j; /** - * 批量处理的grpc回调封装类 + * Batch processing grpc callback wrapper class * * @param */ @@ -95,7 +95,7 @@ public void run(Status status) { } /** - * 不使用计数器latch + * Not using counter latch * * @return */ @@ -158,13 +158,13 @@ public String getErrorMsg() { } /** - * 等待raft执行结束,返回结果给grpc + * Wait for the raft execution to complete, return the result to grpc */ public void waitFinish(StreamObserver observer, Function, V> ok, long timeout) { try { countDownLatch.await(timeout, TimeUnit.MILLISECONDS); - if (errorStatus.isEmpty()) { // 没有错误时,合并结果 + if (errorStatus.isEmpty()) { // No error, merge results observer.onNext(ok.apply(results)); } else { observer.onNext((V) FeedbackRes.newBuilder() @@ -186,7 +186,7 @@ public void waitFinish(StreamObserver observer, Function, V> ok, long } /** - * 从多个结果中选择一个错误的结果返回,如果没有错误,返回第一个 + * Select one incorrect result from multiple results, if there are no errors, return the first one. */ public FeedbackRes selectError(List results) { if (!CollectionUtils.isEmpty(results)) { diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/GrpcClosure.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/GrpcClosure.java index 785739edde..0d65066e99 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/GrpcClosure.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/GrpcClosure.java @@ -36,7 +36,7 @@ abstract class GrpcClosure implements RaftClosure { private V result; /** - * 设置输出结果给raftClosure,对于Follower来说,raftClosure为空 + * Set the output result to raftClosure, for Follower, raftClosure is empty. */ public static void setResult(RaftClosure raftClosure, V result) { GrpcClosure closure = (GrpcClosure) raftClosure; diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreNodeService.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreNodeService.java index 4492f37b2c..0305bd03c7 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreNodeService.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreNodeService.java @@ -100,6 +100,8 @@ public void init() { .isUseRocksDBSegmentLogStorage()); setMaxSegmentFileSize(appConfig.getRaft().getMaxSegmentFileSize()); setMaxReplicatorInflightMsgs(appConfig.getRaft().getMaxReplicatorInflightMsgs()); + setMaxEntriesSize(appConfig.getRaft().getMaxEntriesSize()); + setMaxBodySize(appConfig.getRaft().getMaxBodySize()); }}); setFakePdOptions(new FakePdOptions() {{ setStoreList(appConfig.getFakePdConfig().getStoreList()); @@ -125,9 +127,9 @@ public List getGraphLeaderPartitionIds(String graphName) { } /** - * 添加raft 任务,转发数据给raft + * Add raft task, forward data to raft * - * @return true 表示数据已被提交,false表示未提交,用于单副本入库减少批次拆分 + * @return true means the data has been submitted, false means not submitted, used to reduce batch splitting for single-replica storage */ public void addRaftTask(byte methodId, String graphName, Integer partitionId, Req req, @@ -140,14 +142,14 @@ void addRaftTask(byte methodId, String graphName, Integer partitionId, Req req, } // try { - // 序列化, + // Serialization final byte[] buffer = new byte[req.getSerializedSize() + 1]; final CodedOutputStream output = CodedOutputStream.newInstance(buffer); output.write(methodId); req.writeTo(output); output.checkNoSpaceLeft(); output.flush(); - // 传送给raft + // Add raft task storeEngine.addRaftTask(graphName, partitionId, RaftOperation.create(methodId, buffer, req), closure); @@ -159,7 +161,7 @@ void addRaftTask(byte methodId, String graphName, Integer partitionId, Req req, } /** - * 来自日志的任务,一般是follower 或者 日志回滚的任务 + * Tasks from logs, generally tasks from followers or log rollbacks */ @Override public boolean invoke(int partId, byte[] request, RaftClosure response) throws @@ -181,7 +183,7 @@ public boolean invoke(int partId, byte[] request, RaftClosure response) throws invoke(partId, methodId, CleanReq.parseFrom(input), response); break; default: - return false; // 未处理 + return false; // Unhandled } } catch (IOException e) { throw new HgStoreException(e.getMessage(), e); @@ -190,7 +192,7 @@ public boolean invoke(int partId, byte[] request, RaftClosure response) throws } /** - * 处理raft传送过来的数据 + * Process the data sent by raft */ @Override public boolean invoke(int partId, byte methodId, Object req, RaftClosure response) throws @@ -212,7 +214,7 @@ public boolean invoke(int partId, byte methodId, Object req, RaftClosure respons hgStoreSession.doClean(partId, (CleanReq) req, response); break; default: - return false; // 未处理 + return false; // Unhandled } return true; } diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreSessionImpl.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreSessionImpl.java index b7766ea230..2bc0c27b86 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreSessionImpl.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreSessionImpl.java @@ -130,12 +130,12 @@ public void clean(CleanReq request, String graph = request.getHeader().getGraph(); int partition = request.getPartition(); - // 发给不同的raft执行 + // Send to different raft to execute BatchGrpcClosure closure = new BatchGrpcClosure<>(1); storeService.addRaftTask(HgStoreNodeService.CLEAN_OP, graph, partition, request, closure.newRaftClosure()); - // 等待返回结果 + // Waiting for the return result closure.waitFinish(responseObserver, r -> closure.selectError(r), appConfig.getRaft().getRpcTimeOut()); } @@ -228,7 +228,7 @@ public void batch(BatchReq request, StreamObserver observer) { GraphMode graphMode = graphState.getMode(); if (graphMode != null && graphMode.getNumber() == GraphMode.ReadOnly_VALUE) { - // 状态为只读时从pd获取最新的图状态,图只读状态会在pd的通知中更新 + // When in read-only state, get the latest graph state from pd, the graph's read-only state will be updated in pd's notification. Metapb.Graph pdGraph = pd.getPDClient().getGraph(graph); Metapb.GraphState pdGraphState = @@ -237,13 +237,13 @@ public void batch(BatchReq request, StreamObserver observer) { pdGraphState.getMode() != null && pdGraphState.getMode().getNumber() == GraphMode.ReadOnly_VALUE) { - // 确认pd中存储的当前状态也是只读,则不允许插入数据 + // Confirm that the current state stored in pd is also read-only, then inserting data is not allowed. throw new PDException(-1, "the graph space size " + "has " + "reached the threshold"); } - // pd状态与本地缓存不一致,本地缓存更新为pd中的状态 + // pd status is inconsistent with local cache, update local cache to the status in pd managerGraph.setProtoObj(pdGraph); } } @@ -262,12 +262,12 @@ public void batch(BatchReq request, StreamObserver observer) { return; } - // 按分区拆分数据 + // Split data by partition Map> groups = new HashMap<>(); list.forEach((entry) -> { Key startKey = entry.getStartKey(); if (startKey.getCode() == HgStoreConst.SCAN_ALL_PARTITIONS_ID) { - // 所有Leader分区 + // All Leader partitions List ids = storeService.getGraphLeaderPartitionIds(graph); ids.forEach(id -> { @@ -277,7 +277,7 @@ public void batch(BatchReq request, StreamObserver observer) { groups.get(id).add(entry); }); } else { - // 根据keyCode查询所属分区ID,按分区ID分组 + // According to keyCode to query the belonging partition ID, group by partition ID Integer partitionId = pd.getPartitionByCode(graph, startKey.getCode()) .getId(); @@ -288,7 +288,7 @@ public void batch(BatchReq request, StreamObserver observer) { } }); - // 发给不同的raft执行 + // Send to different raft to execute BatchGrpcClosure closure = new BatchGrpcClosure<>(groups.size()); groups.forEach((partition, entries) -> { @@ -306,7 +306,7 @@ public void batch(BatchReq request, StreamObserver observer) { if (!graph.isEmpty()) { log.debug(" batch: waiting raft..."); - // 等待返回结果 + // Wait for the return result closure.waitFinish(observer, r -> closure.selectError(r), appConfig.getRaft().getRpcTimeOut()); log.debug(" batch: ended waiting"); @@ -382,16 +382,16 @@ public void table(TableReq request, StreamObserver observer) { } String graph = request.getHeader().getGraph(); - // 所有Leader分区 + // All Leader partitions List ids = storeService.getGraphLeaderPartitionIds(graph); - // 按分区拆分数据 + // Split data by partition Map groups = new HashMap<>(); - // 按分区拆分数据 + // Split data by partition ids.forEach(id -> { groups.put(id, request); }); - // 发给不同的raft执行 + // Send to different raft for execution BatchGrpcClosure closure = new BatchGrpcClosure<>(groups.size()); groups.forEach((partition, entries) -> { storeService.addRaftTask(HgStoreNodeService.TABLE_OP, graph, partition, @@ -401,7 +401,7 @@ public void table(TableReq request, StreamObserver observer) { if (!groups.isEmpty()) { // log.info(" table waiting raft..."); - // 等待返回结果 + // Wait for the return result closure.waitFinish(observer, r -> closure.selectError(r), appConfig.getRaft().getRpcTimeOut()); // log.info(" table ended waiting raft"); @@ -470,16 +470,16 @@ public void graph(GraphReq request, StreamObserver observer) { } String graph = request.getHeader().getGraph(); - // 所有Leader分区 + // All Leader partitions List ids = storeService.getGraphLeaderPartitionIds(graph); - // 按分区拆分数据 + // Split data by partition Map groups = new HashMap<>(); - // 按分区拆分数据 + // Split data by partitioning ids.forEach(id -> { groups.put(id, request); }); - // 发给不同的raft执行 + // Send to different raft for execution BatchGrpcClosure closure = new BatchGrpcClosure<>(groups.size()); groups.forEach((partition, entries) -> { storeService.addRaftTask(HgStoreNodeService.GRAPH_OP, graph, partition, @@ -488,7 +488,7 @@ public void graph(GraphReq request, StreamObserver observer) { }); if (!groups.isEmpty()) { - // 等待返回结果 + // Waiting for the return result closure.waitFinish(observer, r -> closure.selectError(r), appConfig.getRaft().getRpcTimeOut()); diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreWrapperEx.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreWrapperEx.java index 78355e1785..26e7f2357f 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreWrapperEx.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/HgStoreWrapperEx.java @@ -113,7 +113,7 @@ public boolean doTable(int partId, TableMethod method, String graph, String tabl public boolean doGraph(int partId, GraphMethod method, String graph) { boolean flag = true; - if (method == GRAPH_METHOD_DELETE) {// 交给 raft 执行,此处不处理 + if (method == GRAPH_METHOD_DELETE) {// Hand over to raft for execution, no processing here flag = true; } else { throw new UnsupportedOperationException("GraphMethod: " + method.name()); diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ParallelScanIterator.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ParallelScanIterator.java index 430d466c0d..1f34b043f6 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ParallelScanIterator.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ParallelScanIterator.java @@ -43,7 +43,7 @@ import lombok.extern.slf4j.Slf4j; /** - * 支持平行读取的批量查询迭代器 + * Support parallel read batch query iterator */ @Slf4j public class ParallelScanIterator implements ScanIterator { @@ -86,7 +86,7 @@ private ParallelScanIterator(Supplier> iter Math.max(1, Math.min(query.getConditionCount() / 16, maxWorkThreads)); } this.maxInQueue = maxWorkThreads * 2; - // 边有序需要更大的队列 + // Edge sorted requires a larger queue queue = new LinkedBlockingQueue<>(maxInQueue * 2); createScanner(); } @@ -107,7 +107,7 @@ public boolean hasNext() { while (current == null && tryTimes < waitDataMaxTryTimes) { try { if (queue.size() != 0 || !finished) { - current = queue.poll(100, TimeUnit.MILLISECONDS); //定期检查client是否被关闭了 + current = queue.poll(100, TimeUnit.MILLISECONDS); // Regularly check if the client has been closed. if (current == null && !finished) { wakeUpScanner(); } @@ -159,7 +159,7 @@ public void close() { } /** - * 创建扫描器 + * Create Scanner */ private void createScanner() { synchronized (scanners) { @@ -173,7 +173,7 @@ private void createScanner() { } /** - * 唤醒扫描器 + * Wake up scanner */ private void wakeUpScanner() { synchronized (pauseScanners) { @@ -187,7 +187,7 @@ private void wakeUpScanner() { } /** - * 休眠扫描器 + * Sleep Scanner * * @param scanner */ @@ -209,10 +209,10 @@ private void quitScanner(KVScanner scanner) { } /** - * 添加到队列,返回队列是否已满 + * Add to queue, return whether the queue is full * * @param data - * @return false: 队列已满 + * @return false: Queue is full */ private boolean putData(List data) { try { @@ -238,7 +238,7 @@ private boolean putData(List data, boolean hasNext) { queueLock.unlock(); } } - // 数据未结束,线程继续执行 + // Data not ended, thread continues to execute return hasNext || this.queue.size() < maxInQueue; } @@ -305,7 +305,7 @@ class KVScanner { private volatile boolean closed = false; private ScanIterator getIterator() { - // 迭代器没有数据,或该点以达到limit,切换新的迭代器 + // Iterator has no data, or the point has reached the limit, switch to a new iterator. if (iterator == null || !iterator.hasNext() || counter >= limit) { if (iterator != null) { iterator.close(); @@ -343,7 +343,7 @@ public void scanKV() { if ((entriesSize >= batchSize || bodySize >= maxBodySize) || (orderEdge && bodySize >= maxBodySize / 2)) { if (orderEdge) { - //边排序,保证一个点的所有边连续,阻止其他点插入 + // Sort the edges, ensure all edges of one point are consecutive, prevent other points from inserting. canNext = putData(dataList, iterator != null && iterator.hasNext()); } else { canNext = putData(dataList); diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanBatchResponse.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanBatchResponse.java index 3712fbd7cc..99ce662fe7 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanBatchResponse.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanBatchResponse.java @@ -37,10 +37,10 @@ import lombok.extern.slf4j.Slf4j; /** - * 批量查询处理器,批量查询数据,流式返回数据。 - * 1、服务端流式发送数据给客户端 - * 2、客户端每消费一批次数据,返回批次号给服务端 - * 3、服务端根据批次号决定发送多少数据,保证传送数据的不间断, + * Batch query processor, batch query data, stream back data. + * 1. Server-side streaming data to the client + * 2. The client returns the batch number to the server after consuming each batch of data. + * 3. The server decides how much data to send based on the batch number, ensuring the uninterrupted transmission of data, */ @Slf4j public class ScanBatchResponse implements StreamObserver { @@ -50,24 +50,24 @@ public class ScanBatchResponse implements StreamObserver { static ByteBufferAllocator alloc = new ByteBufferAllocator(ParallelScanIterator.maxBodySize * 3 / 2, 1000); private final int maxInFlightCount = PropertyUtil.getInt("app.scan.stream.inflight", 16); - private final int activeTimeout = PropertyUtil.getInt("app.scan.stream.timeout", 60); //单位秒 + private final int activeTimeout = PropertyUtil.getInt("app.scan.stream.timeout", 60); // unit: second private final StreamObserver sender; private final HgStoreWrapperEx wrapper; private final ThreadPoolExecutor executor; private final Object stateLock = new Object(); private final Lock iteratorLock = new ReentrantLock(); - // 当前正在遍历的迭代器 + // Currently traversing iterator private ScanIterator iterator; - // 下一次发送的序号 + // Next send sequence number private volatile int seqNo; - // Client已消费的序号 + // Client consumed sequence number private volatile int clientSeqNo; - // 已经发送的条目数 + // Number of entries sent private volatile long count; - // 客户端要求返回的最大条目数 + // Client requests the maximum number of entries to return private volatile long limit; private ScanQueryRequest query; - // 上次读取数据时间 + // Last read data time private long activeTime; private volatile State state; @@ -83,20 +83,20 @@ public ScanBatchResponse(StreamObserver response, HgStoreWrapperEx wra } /** - * 接收客户端发送的消息 - * 服务端另起线程处理消息,不阻塞网络 + * Receive messages sent by the client + * Server starts a new thread to process messages, does not block the network. * * @param request */ @Override public void onNext(ScanStreamBatchReq request) { switch (request.getQueryCase()) { - case QUERY_REQUEST: // 查询条件 + case QUERY_REQUEST: // query conditions executor.execute(() -> { startQuery(request.getHeader().getGraph(), request.getQueryRequest()); }); break; - case RECEIPT_REQUEST: // 消息异步应答 + case RECEIPT_REQUEST: // Message asynchronous response this.clientSeqNo = request.getReceiptRequest().getTimes(); if (seqNo - clientSeqNo < maxInFlightCount) { synchronized (stateLock) { @@ -111,7 +111,7 @@ public void onNext(ScanStreamBatchReq request) { } } break; - case CANCEL_REQUEST: // 关闭流 + case CANCEL_REQUEST: // close stream closeQuery(); break; default: @@ -132,7 +132,7 @@ public void onCompleted() { } /** - * 生成迭代器 + * Generate iterator * * @param request */ @@ -152,7 +152,7 @@ private void startQuery(String graphName, ScanQueryRequest request) { } /** - * 生成迭代器 + * Generate iterator */ private void closeQuery() { setStateDone(); @@ -178,7 +178,7 @@ private void closeIter() { } /** - * 发送数据 + * Send data */ private void sendEntries() { if (state == State.DONE || iterator == null) { @@ -255,7 +255,7 @@ private State setStateIdle() { } /** - * 检查是否活跃,超过一定时间客户端没有请求数据,认为已经不活跃,关闭连接释放资源 + * Check for activity, if the client does not request data for a certain period of time, it is considered inactive, close the connection to release resources. */ public void checkActiveTimeout() { if ((System.currentTimeMillis() - activeTime) > activeTimeout * 1000L) { @@ -265,7 +265,7 @@ public void checkActiveTimeout() { } /** - * 任务状态 + * Task Status */ private enum State { IDLE, diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanBatchResponseFactory.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanBatchResponseFactory.java index 9c6dafc776..43abfd97ce 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanBatchResponseFactory.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanBatchResponseFactory.java @@ -54,7 +54,7 @@ public int removeStreamObserver(StreamObserver observer) { } /** - * 检查是否Stream是否活跃,超时的Stream及时关闭 + * Check if the Stream is active, and close the timed-out Stream in a timely manner. */ public void checkStreamActive() { streamObservers.forEach(streamObserver -> { diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanUtil.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanUtil.java index 0148fa0b25..e2fcff42e5 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanUtil.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/ScanUtil.java @@ -149,7 +149,7 @@ static ScanIterator getIterator(String graph, ScanQueryRequest request, } /** - * 支持并行读取的多迭代器 + * Support for multi-iterators with parallel reading */ static ScanIterator getParallelIterator(String graph, ScanQueryRequest request, HgStoreWrapperEx wrapper, ThreadPoolExecutor executor) { diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/scan/GraphStoreImpl.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/scan/GraphStoreImpl.java index dcfc0549a8..6583e59745 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/scan/GraphStoreImpl.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/scan/GraphStoreImpl.java @@ -34,7 +34,7 @@ import lombok.extern.slf4j.Slf4j; /** - * graphpb.proto 实现类 + * graphpb.proto implementation class */ @Slf4j @GRpcService @@ -67,9 +67,9 @@ public ThreadPoolExecutor getExecutor() { } /** - * 流式回复消息,每个消息带有seqNo - * 客户端每消费一个消息,应答一个seqNo - * 服务端根据客户端的seqNo决定发送几个数据包 + * Streaming reply messages, each message with a seqNo + * Client side should respond with a seqNo for each message consumed. + * The server decides how many packets to send based on the client's seqNo. * * @param ro * @return diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/scan/ScanResponseObserver.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/scan/ScanResponseObserver.java index b5b49d0398..dc57dae368 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/scan/ScanResponseObserver.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/grpc/scan/ScanResponseObserver.java @@ -71,17 +71,17 @@ public class ScanResponseObserver implements private volatile Future readTask; /* - * 2022年11月1日 - * 1.onNext 需要进行异步处理,以防止grpc的调用阻塞 - * 2.不要读取迭代器或者发送数据不要产生线程等待 - * 3.在发送前,尽量准备好要发送的数据 + * November 1, 2022 + * 1. onNext needs to be processed asynchronously to prevent the grpc call from being blocked. + * 2. Do not read iterators or send data do not produce thread waiting. + * 3. Before sending, try to prepare the data to be sent as much as possible. * */ /* - * 2022年11月2日 - * 1.读取rocksdb迭代器的线程read - * 2.进行数据转换并发送到阻塞队列的线程offer - * 3.从阻塞队列读取数据,并发送的线程,包括在没有读取到数据的情况下唤醒读取和发送的线程send + * November 2, 2022 + * 1. Read the thread of rocksdb iterator read + * 2. Perform data conversion and send to the blocking queue thread offer + * 3. Thread for reading data from the blocking queue and sending, including waking up the reading and sending threads when no data is read * */ public ScanResponseObserver(StreamObserver sender, diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/listener/PdConfigureListener.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/listener/PdConfigureListener.java index 709e7fdb9d..d818e5627a 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/listener/PdConfigureListener.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/listener/PdConfigureListener.java @@ -103,7 +103,7 @@ public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { client.listen(TIMESTAMP_KEY, (Consumer) o -> { log.info("receive message to restart :" + o); try { - // 优先更新最新配置文件,以免修改像端口之类的参数导致旧文件被优先加载 + // Prioritize updating the latest configuration file to avoid old files being loaded first when modifying parameters like ports. ScanPrefixResponse responseNew = client.scanPrefix(CONFIG_PREFIX); Map kvsMapNew = responseNew.getKvsMap(); String config = kvsMapNew.get(CONFIG_FIX_PREFIX); diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/util/HgGrpc.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/util/HgGrpc.java index fb824c56aa..0bb68895f6 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/util/HgGrpc.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/util/HgGrpc.java @@ -109,7 +109,7 @@ public static StatusRuntimeException toErr(Status status, String des, Throwable t) { if (t != null) { - // 为给client返回完整异常信息 + // To return complete exception information to the client des = (des == null ? "" : des + ",") + Throwables.getStackTraceAsString(t); } diff --git a/hugegraph-store/hg-store-node/src/main/resources/application-pd.yml b/hugegraph-store/hg-store-node/src/main/resources/application-pd.yml index dc198c3c89..7985e67da1 100644 --- a/hugegraph-store/hg-store-node/src/main/resources/application-pd.yml +++ b/hugegraph-store/hg-store-node/src/main/resources/application-pd.yml @@ -16,7 +16,7 @@ # pdserver: - # pd服务地址,多个pd地址用逗号分割 + # PD service address, multiple PD addresses separated by commas address: localhost:8686 management: @@ -33,6 +33,6 @@ logging: level: root: info rocksdb: - # rocksdb 使用的总内存大小 + # total memory size used by rocksdb total_memory_size: 32000000000 write_buffer_size: 32000000 diff --git a/hugegraph-store/hg-store-node/src/main/resources/application.yml b/hugegraph-store/hg-store-node/src/main/resources/application.yml index 962101aac8..0b65270608 100644 --- a/hugegraph-store/hg-store-node/src/main/resources/application.yml +++ b/hugegraph-store/hg-store-node/src/main/resources/application.yml @@ -16,11 +16,11 @@ # pdserver: - # pd服务地址,多个pd地址用逗号分割 + # PD service address, multiple PD addresses separated by commas address: localhost:8686 grpc: - # grpc的服务地址 + # grpc service address host: 127.0.0.1 port: 8500 netty-server: @@ -28,14 +28,14 @@ grpc: raft: address: 127.0.0.1:8510 max-log-file-size: 600000000000 - # 快照生成时间间隔,单位秒 + # Snapshot generation interval, unit: seconds snapshotInterval: 1800 server: - # rest 服务地址 + # rest service address port: 8520 app: - # 存储路径,支持多个路径,逗号分割 + # Storage path, support multiple paths, separated by commas data-path: ./storage spring: diff --git a/hugegraph-store/hg-store-node/src/test/java/org/apache/hugegraph/store/node/HgStoreNodeServiceTest.java b/hugegraph-store/hg-store-node/src/test/java/org/apache/hugegraph/store/node/HgStoreNodeServiceTest.java index 0ff80ff2e6..336428f998 100644 --- a/hugegraph-store/hg-store-node/src/test/java/org/apache/hugegraph/store/node/HgStoreNodeServiceTest.java +++ b/hugegraph-store/hg-store-node/src/test/java/org/apache/hugegraph/store/node/HgStoreNodeServiceTest.java @@ -27,16 +27,16 @@ import java.util.concurrent.TimeUnit; /** - * HgStore单元测试 - * 1、测试raft多副本入库 - * 2、测试快照同步 - * 3、测试副本增减 - * 4、测试单幅本关闭日志入库 + * HgStore unit testing + * 1. Test raft multi-copy storage entry + * 2. Test snapshot synchronization + * 3, test copy addition and subtraction + * 4. Test single frame with log storage turned off */ public class HgStoreNodeServiceTest { String yml = - "rocksdb:\n" + " # rocksdb 使用的总内存大小\n" + " total_memory_size: 32000000000\n" + + "rocksdb:\n" + " # Total memory size used by rocksdb\n" + " total_memory_size: 32000000000\n" + " max_background_jobs: 8\n" + " max_subcompactions: 4\n" + " target_file_size_multiplier: 4\n" + " min_write_buffer_number_to_merge: 8\n" + " target_file_size_base: 512000000"; diff --git a/hugegraph-store/hg-store-node/src/test/resources/application-pd.yml b/hugegraph-store/hg-store-node/src/test/resources/application-pd.yml index 58673f5c23..4047e27af5 100644 --- a/hugegraph-store/hg-store-node/src/test/resources/application-pd.yml +++ b/hugegraph-store/hg-store-node/src/test/resources/application-pd.yml @@ -16,7 +16,7 @@ # rocksdb: - # rocksdb 使用的总内存大小 + # total memory size used by RocksDB total_memory_size: 32000000000 max_background_jobs: 8 max_subcompactions: 4 diff --git a/hugegraph-store/hg-store-node/src/test/resources/application-server00.yml b/hugegraph-store/hg-store-node/src/test/resources/application-server00.yml index 49b33b2ea2..c4e2c5ed15 100644 --- a/hugegraph-store/hg-store-node/src/test/resources/application-server00.yml +++ b/hugegraph-store/hg-store-node/src/test/resources/application-server00.yml @@ -16,10 +16,10 @@ # pdserver: - # pd服务地址,多个pd地址用逗号分割 + # PD service address, multiple PD addresses separated by commas address: localhost:8686 grpc: - # grpc的服务地址 + # grpc service address host: 127.0.0.1 port: 8500 netty-server: @@ -28,11 +28,11 @@ raft: # enable: false address: 127.0.0.1:8510 data-path: ${app.data-path}/raft - # 快照生成时间间隔,单位秒 + # Snapshot generation interval, unit: seconds snapshotInterval: 30 max-log-file-size: 60000000 server: - # rest 服务地址 + # rest service address port: 8520 app: @@ -60,14 +60,14 @@ rocksdb: snapshot_path: ${app.data-path}/snapshot bloom_filter_bits_per_key: 10 compression_per_level: "[none, zstd, zstd, zstd, zstd, zstd, zstd]" -#fakePd配置参数 +# fakePd configuration parameters fake-pd: - # fake-pd模式下,store grpc集群列表 + # fake-pd mode, store grpc cluster list store-list: 127.0.0.1:8500 - # fake-pd模式下,设置raft集群列表 + # fake-pd mode, set raft cluster list peers-list: 127.0.0.1:8510 - # 分区数量 + # Partition Count partition-count: 10 - # 每个分区副本数量 + # Number of replicas per partition shard-count: 3 diff --git a/hugegraph-store/hg-store-node/src/test/resources/application-server01.yml b/hugegraph-store/hg-store-node/src/test/resources/application-server01.yml index 72482bc28c..0a9c7972f8 100644 --- a/hugegraph-store/hg-store-node/src/test/resources/application-server01.yml +++ b/hugegraph-store/hg-store-node/src/test/resources/application-server01.yml @@ -16,10 +16,10 @@ # pdserver: - # pd服务地址,多个pd地址用逗号分割 + # PD service address, multiple PD addresses separated by commas address: localhost:8686 grpc: - # grpc的服务地址 + # grpc service address host: 127.0.0.1 port: 8501 netty-server: @@ -28,11 +28,11 @@ raft: # enable: false address: 127.0.0.1:8511 useRocksDBSegmentLogStorage: false - # 快照生成时间间隔,单位秒 + # Snapshot generation interval, in seconds snapshotInterval: 300 disruptorBufferSize: 128 server: - # rest 服务地址 + # rest service address port: 8521 app: @@ -58,13 +58,13 @@ rocksdb: write_buffer_size: 2000000 level0_file_num_compaction_trigger: 2 bloom_filter_bits_per_key: 10 -#fakePd配置参数 +# fakePd configuration parameters fake-pd: - # fake-pd模式下,store grpc集群列表 + # fake-pd mode, store grpc cluster list store-list: 127.0.0.1:8501,127.0.0.1:8502,127.0.0.1:8503 - # fake-pd模式下,设置raft集群列表 + # fake-pd mode, set raft cluster list peers-list: 127.0.0.1:8511,127.0.0.1:8512,127.0.0.1:8513 - # 分区数量 + # Partition Number partition-count: 10 - # 每个分区副本数量 + # Number of replicas per partition shard-count: 3 diff --git a/hugegraph-store/hg-store-node/src/test/resources/application-server02.yml b/hugegraph-store/hg-store-node/src/test/resources/application-server02.yml index b69e0535e3..b419a4f054 100644 --- a/hugegraph-store/hg-store-node/src/test/resources/application-server02.yml +++ b/hugegraph-store/hg-store-node/src/test/resources/application-server02.yml @@ -16,10 +16,10 @@ # pdserver: - # pd服务地址,多个pd地址用逗号分割 + # PD service address, multiple PD addresses separated by commas address: localhost:8686 grpc: - # grpc的服务地址 + # grpc service address host: 127.0.0.1 port: 8502 netty-server: @@ -28,11 +28,11 @@ raft: # enable: false address: 127.0.0.1:8512 useRocksDBSegmentLogStorage: false - # 快照生成时间间隔,单位秒 + # Snapshot generation interval, in seconds snapshotInterval: 300 disruptorBufferSize: 128 server: - # rest 服务地址 + # rest service address port: 8522 app: @@ -57,13 +57,13 @@ management: rocksdb: db_max_alive_time: 120 -#fakePd配置参数 +# fakePd configuration parameters fake-pd: - # fake-pd模式下,store grpc集群列表 + # fake-pd mode, store grpc cluster list store-list: 127.0.0.1:8501,127.0.0.1:8502,127.0.0.1:8503 - # fake-pd模式下,设置raft集群列表 + # fake-pd mode, set raft cluster list peers-list: 127.0.0.1:8511,127.0.0.1:8512,127.0.0.1:8513 - # 分区数量 + # Partition Count partition-count: 10 - # 每个分区副本数量 + # Number of replicas per partition shard-count: 3 diff --git a/hugegraph-store/hg-store-node/src/test/resources/application-server03.yml b/hugegraph-store/hg-store-node/src/test/resources/application-server03.yml index 8028dffd9f..709370c3c8 100644 --- a/hugegraph-store/hg-store-node/src/test/resources/application-server03.yml +++ b/hugegraph-store/hg-store-node/src/test/resources/application-server03.yml @@ -16,10 +16,10 @@ # pdserver: - # pd服务地址,多个pd地址用逗号分割 + # PD service address, multiple PD addresses separated by commas address: localhost:8686 grpc: - # grpc的服务地址 + # grpc service address host: 127.0.0.1 port: 8503 netty-server: @@ -29,11 +29,11 @@ raft: address: 127.0.0.1:8513 snapshotLogIndexMargin: 1024 useRocksDBSegmentLogStorage: false - # 快照生成时间间隔,单位秒 + # Snapshot generation interval, in seconds snapshotInterval: 300 disruptorBufferSize: 128 server: - # rest 服务地址 + # rest service address port: 8523 app: @@ -59,13 +59,13 @@ rocksdb: db_max_alive_time: 120 -#fakePd配置参数 +# fakePd configuration parameters fake-pd: - # fake-pd模式下,store grpc集群列表 + # fake-pd mode, store grpc cluster list store-list: 127.0.0.1:8501,127.0.0.1:8502,127.0.0.1:8503 - # fake-pd模式下,设置raft集群列表 + # fake-pd mode, set raft cluster list peers-list: 127.0.0.1:8511,127.0.0.1:8512,127.0.0.1:8513 - # 分区数量 + # Partition Count partition-count: 10 - # 每个分区副本数量 + # Number of replicas per partition shard-count: 3 diff --git a/hugegraph-store/hg-store-node/src/test/resources/application-server04.yml b/hugegraph-store/hg-store-node/src/test/resources/application-server04.yml index b9d35f443d..b06a92c8dd 100644 --- a/hugegraph-store/hg-store-node/src/test/resources/application-server04.yml +++ b/hugegraph-store/hg-store-node/src/test/resources/application-server04.yml @@ -16,10 +16,10 @@ # pdserver: - # pd服务地址,多个pd地址用逗号分割 + # PD service address, multiple PD addresses separated by commas address: localhost:8686 grpc: - # grpc的服务地址 + # grpc service address host: 127.0.0.1 port: 8504 netty-server: @@ -28,10 +28,10 @@ raft: # enable: false address: 127.0.0.1:8514 - # 快照生成时间间隔,单位秒 + # Snapshot generation interval, unit: seconds snapshotInterval: 300 server: - # rest 服务地址 + # rest service address port: 8524 app: @@ -56,13 +56,13 @@ management: rocksdb: -#fakePd配置参数 +# fakePd configuration parameters fake-pd: - # fake-pd模式下,store grpc集群列表 + # fake-pd mode, store grpc cluster list store-list: 127.0.0.1:8501,127.0.0.1:8502,127.0.0.1:8503 - # fake-pd模式下,设置raft集群列表 + # fake-pd mode, set raft cluster list peers-list: 127.0.0.1:8511,127.0.0.1:8512,127.0.0.1:8513 - # 分区数量 + # Partition Number partition-count: 3 - # 每个分区副本数量 + # Number of replicas per partition shard-count: 3 diff --git a/hugegraph-store/hg-store-node/src/test/resources/application-server05.yml b/hugegraph-store/hg-store-node/src/test/resources/application-server05.yml index 02b83f9a5c..e3637051ce 100644 --- a/hugegraph-store/hg-store-node/src/test/resources/application-server05.yml +++ b/hugegraph-store/hg-store-node/src/test/resources/application-server05.yml @@ -16,10 +16,10 @@ # pdserver: - # pd服务地址,多个pd地址用逗号分割 + # PD service address, multiple PD addresses separated by commas address: localhost:8686 grpc: - # grpc的服务地址 + # grpc service address host: 127.0.0.1 port: 8505 netty-server: @@ -28,10 +28,10 @@ raft: # enable: false address: 127.0.0.1:8515 data-path: ${app.data-path}/raft - # 快照生成时间间隔,单位秒 + # Snapshot generation interval, unit: seconds snapshotInterval: 300 server: - # rest 服务地址 + # rest service address port: 8525 app: @@ -58,13 +58,13 @@ rocksdb: wal_path: ${app.data-path}/db snapshot_path: ${app.data-path}/snapshot -#fakePd配置参数 +# fakePd configuration parameters fake-pd: - # fake-pd模式下,store grpc集群列表 + # fake-pd mode, store grpc cluster list store-list: 127.0.0.1:8501,127.0.0.1:8502,127.0.0.1:8503 - # fake-pd模式下,设置raft集群列表 + # fake-pd mode, set raft cluster list peers-list: 127.0.0.1:8511,127.0.0.1:8512,127.0.0.1:8513 - # 分区数量 + # Partition Quantity partition-count: 3 - # 每个分区副本数量 + # Number of replicas per partition shard-count: 3 diff --git a/hugegraph-store/hg-store-node/src/test/resources/application-server06.yml b/hugegraph-store/hg-store-node/src/test/resources/application-server06.yml index eeef451c1c..8574bc3705 100644 --- a/hugegraph-store/hg-store-node/src/test/resources/application-server06.yml +++ b/hugegraph-store/hg-store-node/src/test/resources/application-server06.yml @@ -16,10 +16,10 @@ # pdserver: - # pd服务地址,多个pd地址用逗号分割 + # PD service address, multiple PD addresses separated by commas address: localhost:8686 grpc: - # grpc的服务地址 + # grpc service address host: 127.0.0.1 port: 8506 netty-server: @@ -28,10 +28,10 @@ raft: # enable: false address: 127.0.0.1:8516 data-path: ${app.data-path}/raft - # 快照生成时间间隔,单位秒 + # Snapshot generation interval, in seconds snapshotInterval: 300 server: - # rest 服务地址 + # rest service address port: 8526 app: @@ -58,13 +58,13 @@ rocksdb: wal_path: ${app.data-path}/db snapshot_path: ${app.data-path}/snapshot -#fakePd配置参数 +# fakePd configuration parameters fake-pd: - # fake-pd模式下,store grpc集群列表 + # fake-pd mode, store grpc cluster list store-list: 127.0.0.1:8501,127.0.0.1:8502,127.0.0.1:8503 - # fake-pd模式下,设置raft集群列表 + # fake-pd mode, set raft cluster list peers-list: 127.0.0.1:8511,127.0.0.1:8512,127.0.0.1:8513 - # 分区数量 + # Partition Count partition-count: 3 - # 每个分区副本数量 + # Number of replicas per partition shard-count: 3 diff --git a/hugegraph-store/hg-store-rocksdb/pom.xml b/hugegraph-store/hg-store-rocksdb/pom.xml index 758a283abb..bb463d7ed9 100644 --- a/hugegraph-store/hg-store-rocksdb/pom.xml +++ b/hugegraph-store/hg-store-rocksdb/pom.xml @@ -62,8 +62,6 @@ org.projectlombok lombok - 1.18.22 - provided org.apache.logging.log4j diff --git a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBFactory.java b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBFactory.java index 2ec56fa2bd..ce5dc665a6 100644 --- a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBFactory.java +++ b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBFactory.java @@ -87,7 +87,7 @@ private RocksDBFactory() { watcher.dbSession.getRefCount(), (System.currentTimeMillis() - watcher.timestamp) / 1000); } else { - // 超时强制删除 (30min) + // Force delete after timeout (30min) watcher.dbSession.forceResetRefCount(); } } @@ -188,7 +188,7 @@ public Map getTotalKey() { } /** - * 释放rocksdb对象 + * Release rocksdb object * * @param dbName * @return @@ -213,7 +213,7 @@ public boolean releaseGraphDB(String dbName) { } /** - * 销毁图,并删除数据文件 + * Destroy the graph, and delete the data file. * * @param dbName */ @@ -221,7 +221,7 @@ public void destroyGraphDB(String dbName) { log.info("destroy {} 's rocksdb.", dbName); RocksDBSession dbSession = dbSessionMap.get(dbName); releaseGraphDB(dbName); - //增加删除标记 + // Add delete mark if (dbSession != null) { destroyGraphDBs.add(new DBSessionWatcher(dbSession)); rocksdbChangedListeners.forEach(listener -> { diff --git a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBSession.java b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBSession.java index d1f89262a3..c3356de248 100644 --- a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBSession.java +++ b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBSession.java @@ -358,7 +358,7 @@ private String findLatestDBPath(String path, long version) { if (i == dbCount - 1) { latestDBPath = curDBPath; } else { - // delete old db,在删除队列的文件不要删除 + // delete old db, do not delete files in the deletion queue if (!factory.findPathInRemovedList(curDBPath)) { try { FileUtils.deleteDirectory(new File(curDBPath)); @@ -373,7 +373,7 @@ private String findLatestDBPath(String path, long version) { latestDBPath = Paths.get(parentFile.getPath(), defaultName).toString(); } if (factory.findPathInRemovedList(latestDBPath)) { - // 已经被删除,创建新的目录 + // Has been deleted, create a new directory latestDBPath = Paths.get(parentFile.getPath(), String.format("%s_%d", defaultName, version)) .toString(); diff --git a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/SessionOperator.java b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/SessionOperator.java index 12c0d3759f..e6de91a53c 100644 --- a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/SessionOperator.java +++ b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/SessionOperator.java @@ -38,7 +38,7 @@ public interface SessionOperator { ScanIterator scan(String tableName, byte[] keyFrom, byte[] keyTo, int scanType); /** - * 扫描所有cf指定范围的数据 + * Scan all data in the specified cf range */ ScanIterator scanRaw(byte[] keyFrom, byte[] keyTo, long startSeqNum); @@ -62,7 +62,7 @@ public interface SessionOperator { void deleteRange(String table, byte[] keyFrom, byte[] keyTo) throws DBStoreException; /** - * 删除所有cf指定范围的数据 + * Delete all data specified by the cf range */ void deleteRange(byte[] keyFrom, byte[] keyTo) throws DBStoreException; diff --git a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/SessionOperatorImpl.java b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/SessionOperatorImpl.java index f4f8987151..eca6a83a2a 100644 --- a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/SessionOperatorImpl.java +++ b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/SessionOperatorImpl.java @@ -219,7 +219,7 @@ public void prepare() { } /** - * commit抛出异常后一定要调用rollback,否则会造成cfHandleReadLock未释放 + * commit throws an exception, you must call rollback, otherwise it will cause cfHandleReadLock not to be released. */ @Override public Integer commit() throws DBStoreException { @@ -302,13 +302,13 @@ public ScanIterator scan(String tableName, byte[] keyFrom, byte[] keyTo, int sca } /** - * 遍历所有cf指定范围的数据 - * TODO: rocksdb7.x 不支持 setStartSeqNum,改为使用 Timestamp + * Traverse all data in the specified range of cf + * TODO: rocksdb7.x does not support setStartSeqNum, switch to using Timestamp instead. * refer: https://github.com/facebook/rocksdb/wiki/User-defined-Timestamp */ @Override public ScanIterator scanRaw(byte[] keyFrom, byte[] keyTo, long startSeqNum) { - int kNumInternalBytes = 8; //internal key 增加的8个字节后缀 + int kNumInternalBytes = 8; //internal key added 8-byte suffix Snapshot snapshot = rocksdb().getSnapshot(); Iterator cfIterator = session.getTables().keySet().iterator(); diff --git a/hugegraph-store/hg-store-test/pom.xml b/hugegraph-store/hg-store-test/pom.xml index 59f87eaa6d..36308f449d 100644 --- a/hugegraph-store/hg-store-test/pom.xml +++ b/hugegraph-store/hg-store-test/pom.xml @@ -31,7 +31,6 @@ - 1.18.20 @@ -80,7 +79,6 @@ org.projectlombok lombok - ${lombok.version} org.apache.logging.log4j diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerOneRaftFakePDTest.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerOneRaftFakePDTest.java index b4e19f104d..84584efc0c 100644 --- a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerOneRaftFakePDTest.java +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerOneRaftFakePDTest.java @@ -35,14 +35,14 @@ import org.junit.Assert; /** - * 使用fake-pd,支持raft的单元测试 + * Using fake-pd, supporting unit tests for raft. */ public class HgSessionManagerOneRaftFakePDTest { private static final Map leaderMap = new ConcurrentHashMap<>(); private static final Map storeMap = new ConcurrentHashMap<>(); private static final int partitionCount = 3; - // 需要与store的application.yml的fake-pd.partition-count保持一致 + // Need to be consistent with the store's application.yml fake-pd.partition-count private static final String[] storeAddress = { "127.0.0.1:8500" }; @@ -68,7 +68,7 @@ public static void init() { Arrays.equals(startKey, endKey)) { builder.add(leaderMap.get(startCode % partitionCount), startCode); } else { - Assert.fail("OwnerKey转成HashCode后已经无序了, 按照OwnerKey范围查询没意义"); + Assert.fail("OwnerKey converted to HashCode is no longer ordered, querying by OwnerKey range is meaningless"); builder.add(leaderMap.get(startCode % partitionCount), startCode); builder.add(leaderMap.get(endCode % partitionCount), endCode); } @@ -174,8 +174,8 @@ public void batchGet() { } // @Test - //CAUTION: ONLY FOR LONG! - //注意:目前只可以对long类型value进行Merge操作。 + // CAUTION: ONLY FOR LONG! + // Note: Currently, only Merge operations can be performed on long type values. public void merge() { System.out.println("--- test merge (1+1=2)---"); HgStoreSession session = getStoreSession(); diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerRaftFakePDTest.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerRaftFakePDTest.java index d014864870..cb3eae8a79 100644 --- a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerRaftFakePDTest.java +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerRaftFakePDTest.java @@ -35,16 +35,16 @@ import org.junit.Assert; /** - * 使用fake-pd,支持raft的单元测试 + * Use fake-pd, support unit tests for raft RuntimeMethodHandle.op_Implicit(Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageResult) */ public class HgSessionManagerRaftFakePDTest { private static final Map leaderMap = new ConcurrentHashMap<>(); private static final Map storeMap = new ConcurrentHashMap<>(); private static final int partitionCount = 3; - // 需要与store的application.yml的fake-pd.partition-count保持一致 + // Need to be consistent with the fake-pd.partition-count in the store's application.yml private static final String[] storeAddress = - { // 需要与store的application.yml的fake-pd.store-list保持一致 + { // Need to be consistent with the store's application.yml fake-pd.store-list "127.0.0.1:8501", "127.0.0.1:8502", "127.0.0.1:8503" }; @@ -72,7 +72,7 @@ public static void init() { Arrays.equals(startKey, endKey)) { builder.add(leaderMap.get(startCode % partitionCount), startCode); } else { - Assert.fail("OwnerKey转成HashCode后已经无序了, 按照OwnerKey范围查询没意义"); + Assert.fail("OwnerKey converted to HashCode is no longer ordered, querying by OwnerKey range is meaningless"); builder.add(leaderMap.get(startCode % partitionCount), startCode); builder.add(leaderMap.get(endCode % partitionCount), endCode); } @@ -216,8 +216,8 @@ public void batchGet() { } // @Test - //CAUTION: ONLY FOR LONG! - //注意:目前只可以对long类型value进行Merge操作。 + // CAUTION: ONLY FOR LONG! + // Note: Currently, only Merge operations can be performed on long type values. public void merge() { System.out.println("--- test merge (1+1=2)---"); HgStoreSession session = getStoreSession(); diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerRaftPDTest.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerRaftPDTest.java index 9820457d78..3b7dc64fd5 100644 --- a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerRaftPDTest.java +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerRaftPDTest.java @@ -52,7 +52,7 @@ /** - * 使用pd,支持raft的单元测试 + * Use pd, support unit tests for raft */ @Slf4j public class HgSessionManagerRaftPDTest { @@ -262,8 +262,8 @@ public void testBatchPutMultiGraph() throws IOException { } // @Test - //CAUTION: ONLY FOR LONG! - //注意:目前只可以对long类型value进行Merge操作。 + // CAUTION: ONLY FOR LONG! + // Note: Currently, only long type values can be merged. public void merge() { System.out.println("--- test merge (1+1=2)---"); HgStoreSession session = getStoreSession(); diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerTest.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerTest.java index 9a63ce74ff..1ebaa9462f 100644 --- a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerTest.java +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/HgSessionManagerTest.java @@ -56,7 +56,7 @@ public class HgSessionManagerTest { "unit-test")); private static final int partitionCount = 10; - // 需要与 store 的 application.yml 的 fake-pd.partition-count 保持一致 + // Need to be consistent with the store's application.yml fake-pd.partition-count //private static String[] storeAddress = {"127.0.0.1:8500"}; private static final String[] storeAddress = @@ -91,7 +91,7 @@ public static void init() { //log.info("leader-> {}",leaderMap.get(startCode / PARTITION_LENGTH)); builder.add(leaderMap.get(startCode / PARTITION_LENGTH), startCode); } else { - Assert.fail("OwnerKey 转成 HashCode 后已经无序了,按照 OwnerKey 范围查询没意义"); + Assert.fail("OwnerKey converted to HashCode is already unordered, querying by OwnerKey range is meaningless"); builder.add(leaderMap.get(startCode / PARTITION_LENGTH), startCode); builder.add(leaderMap.get(endCode / PARTITION_LENGTH), endCode); } @@ -172,8 +172,8 @@ public void batchPrefix() { } @Test - //CAUTION: ONLY FOR LONG! - //注意:目前只可以对 long 类型 value 进行 Merge 操作。 + // CAUTION: ONLY FOR LONG! + // Note: Currently, only long type values can be merged. public void merge() { System.out.println("--- test merge (1+1=2)---"); HgStoreSession session = getStoreSession(); diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/PartitionEngineTest.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/PartitionEngineTest.java index 7115aaa65d..1bfe03b543 100644 --- a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/PartitionEngineTest.java +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/PartitionEngineTest.java @@ -78,7 +78,7 @@ public void test() { .contains(peer)) .collect(Collectors.toList()); - // 新增 6、7 + // Add 6, 7 Assert.assertEquals(2, addedNodes.size()); addedNodes.clear(); addedNodes.addAll(Arrays.asList(peers)); @@ -88,7 +88,7 @@ public void test() { addedNodes.forEach(s -> System.out.print(s + " ")); System.out.println(); - // 删除 4,5 + // Delete 4, 5 Assert.assertEquals(2, removedNodes.size()); removedNodes.clear(); @@ -98,7 +98,7 @@ public void test() { Assert.assertEquals(2, removedNodes.size()); removedNodes.forEach(s -> System.out.print(s + " ")); System.out.println(); - // 交集 5 + // Intersection 5 Assert.assertEquals(1, mixedPeer.size()); oldPeers1.removeAll(Arrays.asList(learners)); Assert.assertEquals(1, oldPeers1.size()); diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/client/ChangeShardNumTest.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/client/ChangeShardNumTest.java index be0c869969..f3c94e6691 100644 --- a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/client/ChangeShardNumTest.java +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/client/ChangeShardNumTest.java @@ -27,7 +27,7 @@ import org.junit.Test; /** - * 测试修改副本数 + * Test modify copy number */ public class ChangeShardNumTest extends HgStoreClientBase { diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/client/HgSessionManagerRaftPDTest.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/client/HgSessionManagerRaftPDTest.java index e52ae8d2d7..f6b5e7c353 100644 --- a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/client/HgSessionManagerRaftPDTest.java +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/client/HgSessionManagerRaftPDTest.java @@ -240,8 +240,8 @@ public void testBatchPutMultiGraph() throws IOException { } // @Test - // CAUTION: ONLY FOR LONG! - // 注意:目前只可以对 long 类型 value 进行 Merge 操作。 + // CAUTION: ONLY FOR LONG! + // Note: Currently, only long type values can be merged. public void merge() { System.out.println("--- test merge (1+1=2)---"); HgStoreSession session = getStoreSession(); diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/CoreSuiteTest.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/CoreSuiteTest.java index 9781b06a7b..68530367a0 100644 --- a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/CoreSuiteTest.java +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/CoreSuiteTest.java @@ -39,7 +39,7 @@ // ZipUtilsTest.class, // MiscUtilClassTest.class, // PartitionInstructionProcessorTest.class, -// // 尽量放到最后 +// // Try to put it last // HgBusinessImplTest.class //}) diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/HgCmdClientTest.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/HgCmdClientTest.java index d31e01724a..8468f1b504 100644 --- a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/HgCmdClientTest.java +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/HgCmdClientTest.java @@ -93,8 +93,8 @@ public static String getMd5(String txt) { } public static Long getId() { - // 如果需要更长 或者更大冗余空间,只需要 time * 10^n 即可 - // 当前可保证 1 毫秒 生成 10000 条不重复 + // If needed longer or more redundant space, just use time * 10^n + // Currently guaranteed to generate 10000 non-duplicate in 1 millisecond Long time = Long.valueOf(new SimpleDateFormat("HHmmssSSS").format(new Date())) * 10000 + (long) (Math.random() * 100); // Long time = Long.valueOf(new SimpleDateFormat("MMddhhmmssSSS").format(new Date()) @@ -144,7 +144,7 @@ public Endpoint getPartitionLeader(String graphName, int partitionId) { session.createTable(tableName); String createGraph = "create_graph"; HgOwnerKey hgOwnerKey = toOwnerKey(createGraph); - // 需要写数据,才会创建图 + // Need to write data, then the graph will be created. session.put(tableName, hgOwnerKey, createGraph.getBytes(StandardCharsets.UTF_8)); Assert.assertEquals(createGraph, toStr(session.get(tableName, hgOwnerKey))); @@ -215,7 +215,7 @@ public Endpoint getPartitionLeader(String graphName, int partitionId) { session.createTable(tableName); String createGraph = "create_graph"; HgOwnerKey hgOwnerKey = toOwnerKey(createGraph); - // 需要写数据,才会创建图 + // Need to write data, then the graph will be created. session.put(tableName, hgOwnerKey, createGraph.getBytes(StandardCharsets.UTF_8)); Assert.assertEquals(createGraph, toStr(session.get(tableName, hgOwnerKey))); @@ -264,7 +264,7 @@ public Endpoint getPartitionLeader(String graphName, int partitionId) { session.createTable(tableName); String createGraph = "create_graph"; HgOwnerKey hgOwnerKey = toOwnerKey(createGraph); - // 需要写数据,才会创建图 + // Need to write data, then the graph will be created. session.put(tableName, hgOwnerKey, createGraph.getBytes(StandardCharsets.UTF_8)); Assert.assertEquals(createGraph, toStr(session.get(tableName, hgOwnerKey))); diff --git a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/StoreEngineTestBase.java b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/StoreEngineTestBase.java index 267b5a566d..67596dc103 100644 --- a/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/StoreEngineTestBase.java +++ b/hugegraph-store/hg-store-test/src/main/java/org/apache/hugegraph/store/core/StoreEngineTestBase.java @@ -38,7 +38,7 @@ import lombok.extern.slf4j.Slf4j; /** - * 使用 FakePd 和 FakePdOptions,初始化 HgStoreEngine,该类的各项 get 函数可用 + * Use FakePd and FakePdOptions to initialize HgStoreEngine, the get functions of this class are available. */ @Slf4j public class StoreEngineTestBase { @@ -92,7 +92,7 @@ public static Partition getPartition(int partitionId, String graphName) { } /** - * 创建 分区为 0 的 partition engine. 该分区 1 个 shard,为 leader, graph name: graph0 + * Create partition 0's partition engine. The partition has 1 shard, as the leader, graph name: graph0. * * @return */ diff --git a/hugegraph-store/hg-store-test/src/main/resources/pd-server.yml b/hugegraph-store/hg-store-test/src/main/resources/pd-server.yml index 5608dc9dd4..5782782028 100644 --- a/hugegraph-store/hg-store-test/src/main/resources/pd-server.yml +++ b/hugegraph-store/hg-store-test/src/main/resources/pd-server.yml @@ -41,31 +41,31 @@ pd: patrol-interval: 3000000 data-path: tmp/8686 - # 最少节点数,少于该数字,集群停止入库 + # Minimum number of nodes, less than this number, the cluster stops ingesting data. initial-store-count: 1 - # 初始store列表,在列表内的store自动激活 + # Initial store list, stores within the list are automatically activated. initial-store-list: 127.0.0.1:8501,127.0.0.1:8502,127.0.0.1:8503 #initial-store-list: 127.0.0.1:8501 raft: address: 127.0.0.1:8610 - # raft集群 + # raft cluster peers-list: 127.0.0.1:8610 - # raft rpc读写超时时间,单位毫秒 + # raft rpc read-write timeout, unit in milliseconds rpc-timeout: 10000 - # 快照生成时间间隔,单位秒 + # Snapshot generation interval, unit: seconds snapshotInterval: 30000 metrics: true store: - # store心跳超时时间,超过该时间,认为store临时不可用,转移Leader到其他副本,单位秒 + # store heartbeat timeout, if exceeds this time, consider the store temporarily unavailable, transfer Leader to another replica, in seconds keepAlive-timeout: 300 - # store下线时间。超过该时间,认为store永久不可用,分配副本到其他机器,单位秒 + # store offline time. Beyond this time, it is considered that the store is permanently unavailable, and the replica is allocated to other machines, in seconds. max-down-time: 180000 partition: - # 默认每个分区副本数 + # Default number of replicas per partition default-shard-count: 3 - # 默认每机器最大副本数,初始分区数= store-max-shard-count * store-number / default-shard-count + # Default maximum number of replicas per machine, initial number of partitions = store-max-shard-count * store-number / default-shard-count store-max-shard-count: 1 discovery: - #客户端注册后,无心跳最长次数,超过后,之前的注册信息会被删除 + # After client registration, no heartbeat longest number, after exceeding, previous registration information will be deleted. heartbeat-try-count: 3 diff --git a/install-dist/scripts/dependency/known-dependencies.txt b/install-dist/scripts/dependency/known-dependencies.txt index 1bbf7241fe..02b5dda11a 100644 --- a/install-dist/scripts/dependency/known-dependencies.txt +++ b/install-dist/scripts/dependency/known-dependencies.txt @@ -1,6 +1,7 @@ accessors-smart-1.2.jar airline-0.8.jar android-json-0.0.20131108.vaadin1.jar +animal-sniffer-annotations-1.18.jar animal-sniffer-annotations-1.19.jar annotations-13.0.jar annotations-4.1.1.4.jar @@ -25,6 +26,7 @@ assertj-core-3.19.0.jar ast-9.0-9.0.20190305.jar audience-annotations-0.5.0.jar auto-service-annotations-1.0.jar +bolt-1.6.2.jar bolt-1.6.4.jar byte-buddy-1.10.20.jar byte-buddy-1.10.5.jar @@ -55,11 +57,13 @@ commons-collections4-4.4.jar commons-compress-1.21.jar commons-configuration-1.10.jar commons-configuration2-2.8.0.jar +commons-io-2.12.0.jar commons-io-2.7.jar commons-io-2.8.0.jar commons-lang-2.6.jar commons-lang3-3.11.jar commons-lang3-3.12.0.jar +commons-lang3-3.13.0.jar commons-logging-1.1.1.jar commons-logging-1.2.jar commons-math3-3.2.jar @@ -104,21 +108,28 @@ groovy-jsr223-2.5.14-indy.jar groovy-swing-2.5.14.jar groovy-templates-2.5.14.jar groovy-xml-2.5.14.jar +grpc-api-1.28.1.jar grpc-api-1.39.0.jar grpc-api-1.47.0.jar +grpc-context-1.28.1.jar grpc-context-1.39.0.jar grpc-context-1.47.0.jar +grpc-core-1.28.1.jar grpc-core-1.39.0.jar grpc-core-1.47.0.jar grpc-grpclb-1.39.0.jar grpc-netty-1.39.0.jar grpc-netty-1.47.0.jar +grpc-netty-shaded-1.28.0.jar grpc-netty-shaded-1.39.0.jar grpc-netty-shaded-1.47.0.jar +grpc-protobuf-1.28.0.jar grpc-protobuf-1.39.0.jar +grpc-protobuf-lite-1.28.0.jar grpc-protobuf-lite-1.39.0.jar grpc-services-1.39.0.jar grpc-spring-boot-starter-4.5.5.jar +grpc-stub-1.28.0.jar grpc-stub-1.39.0.jar grpc-stub-1.47.0.jar gson-2.8.6.jar @@ -134,6 +145,7 @@ hbase-shaded-endpoint-2.0.6.jar HdrHistogram-2.1.12.jar HdrHistogram-2.1.9.jar hessian-3.3.6.jar +hessian-3.3.7.jar hg-pd-client-1.5.0.jar hg-pd-common-1.5.0.jar hg-pd-core-1.5.0.jar @@ -318,8 +330,8 @@ log4j-jul-2.17.2.jar log4j-slf4j-impl-2.15.0.jar log4j-slf4j-impl-2.17.0.jar log4j-slf4j-impl-2.17.1.jar +log4j-slf4j-impl-2.18.0.jar logging-interceptor-4.10.0.jar -lombok-1.18.20.jar lombok-1.18.24.jar lookout-api-1.4.1.jar lucene-analyzers-common-8.11.2.jar @@ -328,6 +340,7 @@ lucene-core-8.11.2.jar lucene-queries-4.7.2.jar lucene-queryparser-4.7.2.jar lucene-sandbox-4.7.2.jar +lz4-java-1.4.0.jar lz4-java-1.8.0.jar metrics-annotation-4.2.4.jar metrics-core-3.0.2.jar @@ -388,6 +401,7 @@ osgi-resource-locator-1.0.3.jar parboiled-core-1.2.0.jar parboiled-scala_2.12-1.2.0.jar parser-9.0-9.0.20190305.jar +perfmark-api-0.19.0.jar perfmark-api-0.23.0.jar perfmark-api-0.25.0.jar picocli-4.3.2.jar @@ -401,10 +415,12 @@ powermock-module-junit4-2.0.0-RC.3.jar powermock-module-junit4-common-2.0.0-RC.3.jar powermock-module-junit4-rule-2.0.0-RC.3.jar powermock-reflect-2.0.0-RC.3.jar +protobuf-java-3.11.0.jar protobuf-java-3.17.2.jar protobuf-java-3.21.7.jar protobuf-java-3.5.1.jar protobuf-java-util-3.17.2.jar +proto-google-common-protos-1.17.0.jar proto-google-common-protos-2.0.1.jar protostuff-api-1.6.0.jar protostuff-collectionschema-1.6.0.jar @@ -440,6 +456,8 @@ sjk-stacktrace-0.22.jar slf4j-api-1.7.21.jar slf4j-api-1.7.25.jar slf4j-api-1.7.32.jar +slf4j-api-2.0.9.jar +snakeyaml-1.18.jar snakeyaml-1.26.jar snakeyaml-1.27.jar snakeyaml-1.28.jar diff --git a/pom.xml b/pom.xml index 44be456375..1fa07660ee 100644 --- a/pom.xml +++ b/pom.xml @@ -87,21 +87,37 @@ 1.5.0 - 1.3.0 + 1.5.0 + 1.18.30 hugegraph - UTF-8 11 11 + UTF-8 bash + 1.5.0 hugegraph-server hugegraph-pd hugegraph-store + hugegraph-commons install-dist + hugegraph-cluster-test + + + + org.projectlombok + lombok + ${lombok.version} + provided + true + + + + @@ -151,6 +167,7 @@ **/*.conf **/*.map **/*.properties + **/*.template **/bin/hugegraph.service **/swagger-ui/**/* scripts/dev/reviewers @@ -272,6 +289,7 @@ **/*.txt **/.flattened-pom.xml + **/apache-hugegraph-*/**/*