diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml deleted file mode 100644 index 16171d26ca2..00000000000 --- a/.github/workflows/ci.yaml +++ /dev/null @@ -1,88 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -# This workflow will build a Java project with Maven -# See also: -# https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: CI - -on: - push: - branches: [ '*' ] - pull_request: - branches: [ '*' ] - -jobs: - mvn: - strategy: - matrix: - profile: - - name: 'full-build-jdk8' - jdk: 8 - args: '-Pfull-build apache-rat:check verify -DskipTests spotbugs:check checkstyle:check' - - name: 'full-build-jdk11' - jdk: 11 - args: '-Pfull-build apache-rat:check verify -DskipTests spotbugs:check checkstyle:check' - - name: 'full-build-java-tests' - jdk: 11 - args: '-Pfull-build verify -Dsurefire-forkcount=1 -DskipCppUnit -Dsurefire.rerunFailingTestsCount=5' - - name: 'full-build-cppunit-tests' - jdk: 11 - args: '-Pfull-build verify -Dtest=_ -DfailIfNoTests=false' - fail-fast: false - timeout-minutes: 360 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK ${{ matrix.profile.jdk }} - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.profile.jdk }} - - name: Cache local maven repository - uses: actions/cache@v2 - with: - path: | - ~/.m2/repository/ - !~/.m2/repository/org/apache/zookeeper - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - name: Show the first log message - run: git log -n1 - - name: Install C Dependencies - run: sudo apt-get install libcppunit-dev libsasl2-dev - - name: Build with Maven (${{ matrix.profile.name }}) - run: mvn -B -V -e -ntp "-Dstyle.color=always" ${{ matrix.profile.args }} - env: - MAVEN_OPTS: -Djansi.force=true - - name: Upload unit test results - if: ${{ failure() }} - uses: actions/upload-artifact@v2 - with: - name: surefire-reports-${{ matrix.profile.name }} - path: ./**/target/surefire-reports/ - if-no-files-found: ignore - - name: Upload integration test results - if: ${{ failure() }} - uses: actions/upload-artifact@v2 - with: - name: failsafe-reports-${{ matrix.profile.name }} - path: ./**/target/failsafe-reports/ - if-no-files-found: ignore - diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 00000000000..418ff13f92b --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,33 @@ +name: Run Tests With Clover +on: + workflow_dispatch: +jobs: + build: + name: Build + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Cache Maven packages + uses: actions/cache@v1 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + # Configure credentials + - uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: eu-west-1 + # Run build steps + - run: mvn clean clover:setup + - run: mvn test + - run: mvn clover:aggregate clover:clover + if: always() + - run: aws s3 cp ./target/site/clover/clover.xml s3://codescene-on-prem/code-coverage-data/apache/zookeeper/clover.xml diff --git a/.github/workflows/manual.yaml b/.github/workflows/manual.yaml deleted file mode 100644 index 191a8b0cdd4..00000000000 --- a/.github/workflows/manual.yaml +++ /dev/null @@ -1,85 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -# This workflow will build a Java project with Maven -# See also: -# https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven -# https://docs.github.com/en/actions/reference/events-that-trigger-workflows#manual-events - -name: Manual Build - -on: - workflow_dispatch: - inputs: - buildRef: - description: Ref to build (commit, branch, or refs/pull/1234/head or refs/pull/1234/merge) - required: true - default: refs/pull/1234/merge - mvnOpts: - description: Maven options - required: true - default: --fail-at-end - goals: - description: Maven goals - required: true - default: -Pfull-build apache-rat:check verify -DskipTests spotbugs:check checkstyle:check javadoc:jar -jobs: - mvn: - name: mvn (triggered by ${{ github.event.sender.login }}) - timeout-minutes: 360 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: ${{ github.event.inputs.buildRef }} - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - java-version: 11 - - name: Cache local maven repository - uses: actions/cache@v2 - with: - path: | - ~/.m2/repository/ - !~/.m2/repository/org/apache/zookeeper - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - name: Show the first log message - run: git log -n1 - - name: Install C Dependencies - run: sudo apt-get install libcppunit-dev libsasl2-dev - - name: Build with Maven - run: mvn -B -V -e -ntp "-Dstyle.color=always" ${{ github.event.inputs.mvnOpts }} ${{ github.event.inputs.goals }} - env: - MAVEN_OPTS: -Djansi.force=true - - name: Upload unit test results - if: ${{ failure() }} - uses: actions/upload-artifact@v2 - with: - name: surefire-reports - path: ./**/target/surefire-reports/ - if-no-files-found: ignore - - name: Upload integration test results - if: ${{ failure() }} - uses: actions/upload-artifact@v2 - with: - name: failsafe-reports - path: ./**/target/failsafe-reports/ - if-no-files-found: ignore - diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml new file mode 100644 index 00000000000..dade8aa87b5 --- /dev/null +++ b/.github/workflows/sonar.yml @@ -0,0 +1,32 @@ +name: Run Sonar Analysis +on: + workflow_dispatch: +jobs: + build: + name: Build + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Cache SonarCloud packages + uses: actions/cache@v1 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache Maven packages + uses: actions/cache@v1 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + # Run build steps + - run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -DskipTests -e + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/README.md b/README.md index a616babfdff..e443a281e7d 100644 --- a/README.md +++ b/README.md @@ -51,3 +51,4 @@ We always welcome new contributors to the project! See [How to Contribute](https [mcLink]: https://zookeeper.apache.org/releases [trBadge]: https://travis-ci.org/apache/zookeeper.svg?branch=master [trLink]: https://travis-ci.org/apache/zookeeper +A diff --git a/pom.xml b/pom.xml index 8782ad77322..39bf7445cd3 100755 --- a/pom.xml +++ b/pom.xml @@ -448,6 +448,10 @@ + + zookeeper + knorrest + https://sonarcloud.io 1.8 1.8 @@ -683,7 +687,6 @@ true - -Werror -Xlint:deprecation -Xlint:unchecked -Xlint:-options diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java index 1ff4512156b..91bbe2cab57 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java @@ -1548,6 +1548,248 @@ public synchronized int getXid() { return xid++; } + public ReplyHeader submitRequest( + RequestHeader h, + Record request, + Record response, + WatchRegistration watchRegistration) throws InterruptedException { + return submitRequest(h, request, response, watchRegistration, null); + } + + public ReplyHeader submitRequest( + RequestHeader h, + Record request, + Record response, + WatchRegistration watchRegistration, + WatchDeregistration watchDeregistration) throws InterruptedException { + ReplyHeader r = new ReplyHeader(); + Packet packet = queuePacket( + h, + r, + request, + response, + null, + null, + null, + null, + watchRegistration, + watchDeregistration); + synchronized (packet) { + if (requestTimeout > 0) { + // Wait for request completion with timeout + waitForPacketFinish(r, packet); + } else { + // Wait for request completion infinitely + while (!packet.finished) { + packet.wait(); + } + } + } + if (r.getErr() == Code.REQUESTTIMEOUT.intValue()) { + sendThread.cleanAndNotifyState(); + } + return r; + } + + /** + * Wait for request completion with timeout. + */ + private void waitForPacketFinish(ReplyHeader r, Packet packet) throws InterruptedException { + long waitStartTime = Time.currentElapsedTime(); + while (!packet.finished) { + packet.wait(requestTimeout); + if (!packet.finished && ((Time.currentElapsedTime() - waitStartTime) >= requestTimeout)) { + LOG.error("Timeout error occurred for the packet '{}'.", packet); + r.setErr(Code.REQUESTTIMEOUT.intValue()); + break; + } + } + } + + public void saslCompleted() { + sendThread.getClientCnxnSocket().saslCompleted(); + } + + public void sendPacket(Record request, Record response, AsyncCallback cb, int opCode) throws IOException { + // Generate Xid now because it will be sent immediately, + // by call to sendThread.sendPacket() below. + int xid = getXid(); + RequestHeader h = new RequestHeader(); + h.setXid(xid); + h.setType(opCode); + + ReplyHeader r = new ReplyHeader(); + r.setXid(xid); + + Packet p = new Packet(h, r, request, response, null, false); + p.cb = cb; + sendThread.sendPacket(p); + } + + public ReplyHeader submitRequest( + RequestHeader h, + Record request, + Record response, + WatchRegistration watchRegistration) throws InterruptedException { + return submitRequest(h, request, response, watchRegistration, null); + } + + public ReplyHeader submitRequest( + RequestHeader h, + Record request, + Record response, + WatchRegistration watchRegistration, + WatchDeregistration watchDeregistration) throws InterruptedException { + ReplyHeader r = new ReplyHeader(); + Packet packet = queuePacket( + h, + r, + request, + response, + null, + null, + null, + null, + watchRegistration, + watchDeregistration); + synchronized (packet) { + if (requestTimeout > 0) { + // Wait for request completion with timeout + waitForPacketFinish(r, packet); + } else { + // Wait for request completion infinitely + while (!packet.finished) { + packet.wait(); + } + } + } + if (r.getErr() == Code.REQUESTTIMEOUT.intValue()) { + sendThread.cleanAndNotifyState(); + } + return r; + } + + /** + * Wait for request completion with timeout. + */ + private void waitForPacketFinish(ReplyHeader r, Packet packet) throws InterruptedException { + long waitStartTime = Time.currentElapsedTime(); + while (!packet.finished) { + packet.wait(requestTimeout); + if (!packet.finished && ((Time.currentElapsedTime() - waitStartTime) >= requestTimeout)) { + LOG.error("Timeout error occurred for the packet '{}'.", packet); + r.setErr(Code.REQUESTTIMEOUT.intValue()); + break; + } + } + } + + public void saslCompleted() { + sendThread.getClientCnxnSocket().saslCompleted(); + } + + public void sendPacket(Record request, Record response, AsyncCallback cb, int opCode) throws IOException { + // Generate Xid now because it will be sent immediately, + // by call to sendThread.sendPacket() below. + int xid = getXid(); + RequestHeader h = new RequestHeader(); + h.setXid(xid); + h.setType(opCode); + + ReplyHeader r = new ReplyHeader(); + r.setXid(xid); + + Packet p = new Packet(h, r, request, response, null, false); + p.cb = cb; + sendThread.sendPacket(p); + } + + public ReplyHeader submitRequest( + RequestHeader h, + Record request, + Record response, + WatchRegistration watchRegistration) throws InterruptedException { + return submitRequest(h, request, response, watchRegistration, null); + } + + public ReplyHeader submitRequest( + RequestHeader h, + Record request, + Record response, + WatchRegistration watchRegistration, + WatchDeregistration watchDeregistration) throws InterruptedException { + ReplyHeader r = new ReplyHeader(); + Packet packet = queuePacket( + h, + r, + request, + response, + null, + null, + null, + null, + watchRegistration, + watchDeregistration); + synchronized (packet) { + if (requestTimeout > 0) { + // Wait for request completion with timeout + waitForPacketFinish(r, packet); + } else { + // Wait for request completion infinitely + while (!packet.finished) { + packet.wait(); + } + } + } + if (r.getErr() == Code.REQUESTTIMEOUT.intValue()) { + sendThread.cleanAndNotifyState(); + } + return r; + } + + /** + * Wait for request completion with timeout. + */ + private void waitForPacketFinish(ReplyHeader r, Packet packet) throws InterruptedException { + long waitStartTime = Time.currentElapsedTime(); + while (!packet.finished) { + packet.wait(requestTimeout); + if (!packet.finished && ((Time.currentElapsedTime() - waitStartTime) >= requestTimeout)) { + if (!packet.finished && ((Time.currentElapsedTime() - waitStartTime) >= requestTimeout)) { + if (!packet.finished && ((Time.currentElapsedTime() - waitStartTime) >= requestTimeout)) { + if (!packet.finished && ((Time.currentElapsedTime() - waitStartTime) >= requestTimeout)) { + if (!packet.finished && ((Time.currentElapsedTime() - waitStartTime) >= requestTimeout)) { + LOG.error("Timeout error occurred for the packet '{}'.", packet); + r.setErr(Code.REQUESTTIMEOUT.intValue()); + break; + } + } + } + } + } + } + } + + public void saslCompleted() { + sendThread.getClientCnxnSocket().saslCompleted(); + } + + public void sendPacket(Record request, Record response, AsyncCallback cb, int opCode) throws IOException { + // Generate Xid now because it will be sent immediately, + // by call to sendThread.sendPacket() below. + int xid = getXid(); + RequestHeader h = new RequestHeader(); + h.setXid(xid); + h.setType(opCode); + + ReplyHeader r = new ReplyHeader(); + r.setXid(xid); + + Packet p = new Packet(h, r, request, response, null, false); + p.cb = cb; + sendThread.sendPacket(p); + } + public ReplyHeader submitRequest( RequestHeader h, Record request,