Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7446dcc659 | |||
| 42e06245e1 | |||
| 36d44ed7a4 | |||
| 68846b6676 | |||
| a651d478b0 | |||
| 3c480f19f8 | |||
| 32a35781b5 | |||
| 59111ea53c | |||
| 982a95451d | |||
| be2fb5d89e | |||
| d213f72138 | |||
| 824bcf060d | |||
| dbedcdfe16 | |||
| 87b39fca7b | |||
| d052555ba7 | |||
| dfa2753619 | |||
| 0a47bb6338 | |||
| 25228af9f0 | |||
| d4fba87e13 | |||
| 9919230a3b | |||
| ba9bc9ea93 | |||
| eea6e72145 | |||
| c68b865798 | |||
| 41d35fe745 | |||
| c2d10bb929 | |||
| f3e05e1bc7 | |||
| 90664f4007 | |||
| 2c233437da | |||
| 84c5295345 | |||
| 6d139329f1 | |||
| b5caee443e | |||
| 053979d4e1 | |||
| d57da1e60f | |||
| 3613df6974 | |||
| 0acf0d0834 | |||
| 5ed9da4036 | |||
| 84a37b8a8d | |||
| c292c27444 | |||
| 744abd47ff | |||
| 9f301337b6 | |||
| 0a401b164c | |||
| 7b08820d1a | |||
| 83995ba5fa | |||
| d586567fd6 | |||
| 3505aee124 | |||
| ee3dcda8ea | |||
| c01946fc05 | |||
| 09cb00db19 |
@@ -0,0 +1,124 @@
|
|||||||
|
name: Publish JUnit Report (Short Names)
|
||||||
|
description: Normalize JUnit XML report names and publish a test report to the repo.
|
||||||
|
inputs:
|
||||||
|
token:
|
||||||
|
description: Gitea token with write access to the repository.
|
||||||
|
required: true
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Normalize JUnit report names
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p junit-short
|
||||||
|
shopt -s globstar nullglob
|
||||||
|
for f in **/target/*-reports/TEST-*.xml; do
|
||||||
|
base="$(basename "$f")"
|
||||||
|
short="${base#TEST-}"
|
||||||
|
cp "$f" "junit-short/${short}"
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Generate Markdown Test Report
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p reports
|
||||||
|
python3 - <<'EOF'
|
||||||
|
import glob, xml.etree.ElementTree as ET
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
generated_at = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||||
|
|
||||||
|
# --- JUnit ---
|
||||||
|
files = glob.glob("junit-short/*.xml")
|
||||||
|
total_tests = total_failures = total_errors = total_skipped = 0
|
||||||
|
test_rows = []
|
||||||
|
|
||||||
|
for f in sorted(files):
|
||||||
|
tree = ET.parse(f)
|
||||||
|
r = tree.getroot()
|
||||||
|
suites = r.findall("testsuite") if r.tag == "testsuites" else [r]
|
||||||
|
for ts in suites:
|
||||||
|
name = ts.get("name", f)
|
||||||
|
tests = int(ts.get("tests", 0))
|
||||||
|
failures = int(ts.get("failures", 0))
|
||||||
|
errors = int(ts.get("errors", 0))
|
||||||
|
skipped = int(ts.get("skipped", 0))
|
||||||
|
passed = tests - failures - errors - skipped
|
||||||
|
status = "✅" if (failures + errors) == 0 else "❌"
|
||||||
|
total_tests += tests
|
||||||
|
total_failures += failures
|
||||||
|
total_errors += errors
|
||||||
|
total_skipped += skipped
|
||||||
|
test_rows.append(f"| {status} | {name} | {tests} | {passed} | {failures + errors} | {skipped} |")
|
||||||
|
|
||||||
|
total_passed = total_tests - total_failures - total_errors - total_skipped
|
||||||
|
overall = "✅ All tests passed" if (total_failures + total_errors) == 0 else "❌ Some tests failed"
|
||||||
|
|
||||||
|
# --- JaCoCo ---
|
||||||
|
def counter(el, type_):
|
||||||
|
c = next((x for x in el.findall("counter") if x.get("type") == type_), None)
|
||||||
|
if c is None:
|
||||||
|
return 0, 0
|
||||||
|
covered = int(c.get("covered", 0))
|
||||||
|
missed = int(c.get("missed", 0))
|
||||||
|
return covered, covered + missed
|
||||||
|
|
||||||
|
cov_rows = []
|
||||||
|
jacoco_files = glob.glob("**/target/site/jacoco/jacoco.xml", recursive=True)
|
||||||
|
|
||||||
|
for jf in sorted(jacoco_files):
|
||||||
|
tree = ET.parse(jf)
|
||||||
|
root = tree.getroot()
|
||||||
|
for pkg in root.findall("package"):
|
||||||
|
name = pkg.get("name", "").replace("/", ".")
|
||||||
|
line_cov, line_total = counter(pkg, "LINE")
|
||||||
|
branch_cov, branch_total = counter(pkg, "BRANCH")
|
||||||
|
line_pct = f"{100 * line_cov / line_total:.0f}%" if line_total else "n/a"
|
||||||
|
branch_pct = f"{100 * branch_cov / branch_total:.0f}%" if branch_total else "n/a"
|
||||||
|
cov_rows.append(f"| {name} | {line_pct} ({line_cov}/{line_total}) | {branch_pct} ({branch_cov}/{branch_total}) |")
|
||||||
|
|
||||||
|
# --- Markdown zusammenbauen ---
|
||||||
|
md = (
|
||||||
|
"# Test Report\n\n"
|
||||||
|
f"_Generated on {generated_at}_\n\n"
|
||||||
|
f"**{overall}**\n\n"
|
||||||
|
"## Test Results\n\n"
|
||||||
|
"| | Tests | Passed | Failed | Skipped |\n"
|
||||||
|
"|---|---|---|---|---|\n"
|
||||||
|
f"| **Total** | {total_tests} | {total_passed} | {total_failures + total_errors} | {total_skipped} |\n\n"
|
||||||
|
"### Details\n\n"
|
||||||
|
"| Status | Suite | Tests | Passed | Failed | Skipped |\n"
|
||||||
|
"|---|---|---|---|---|---|\n"
|
||||||
|
) + "\n".join(test_rows) + "\n\n"
|
||||||
|
|
||||||
|
if cov_rows:
|
||||||
|
md += (
|
||||||
|
"## Coverage\n\n"
|
||||||
|
"| Package | Line Coverage | Branch Coverage |\n"
|
||||||
|
"|---|---|---|\n"
|
||||||
|
) + "\n".join(cov_rows) + "\n"
|
||||||
|
else:
|
||||||
|
md += "_No JaCoCo report found._\n"
|
||||||
|
|
||||||
|
with open("reports/test.md", "w") as out:
|
||||||
|
out.write(md)
|
||||||
|
print(md)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Commit Test-Report to Repo
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GIT_USER: gitea-actions-bot
|
||||||
|
GIT_EMAIL: bot@mein-gateway.de
|
||||||
|
GITEA_TOKEN: ${{ inputs.token }}
|
||||||
|
run: |
|
||||||
|
git config user.name "$GIT_USER"
|
||||||
|
git config user.email "$GIT_EMAIL"
|
||||||
|
git remote set-url origin https://$GIT_USER:$GITEA_TOKEN@git.mein-gateway.de/${{ github.repository }}.git
|
||||||
|
git fetch origin
|
||||||
|
git checkout ${{ github.ref_name }}
|
||||||
|
git add reports/
|
||||||
|
git diff --cached --quiet && echo "No changes" && exit 0
|
||||||
|
git commit -m "ci: update test report [skip ci]"
|
||||||
|
git push origin ${{ github.ref_name }}
|
||||||
+2
-10
@@ -1,6 +1,6 @@
|
|||||||
name: "Setup Maven with GitHub Packages"
|
name: "Setup Maven with GitHub Packages"
|
||||||
|
|
||||||
description: "Sets up JDK, caches Maven dependencies, and configures GitHub Packages for Maven repositories."
|
description: "Sets up JDK and caches Maven dependencies."
|
||||||
|
|
||||||
inputs:
|
inputs:
|
||||||
java-version:
|
java-version:
|
||||||
@@ -15,15 +15,7 @@ runs:
|
|||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- name: Set up JDK
|
- name: Set up JDK
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
with:
|
||||||
distribution: ${{ inputs.java-distribution }}
|
distribution: ${{ inputs.java-distribution }}
|
||||||
java-version: ${{ inputs.java-version }}
|
java-version: ${{ inputs.java-version }}
|
||||||
|
uses: actions/setup-java@v5
|
||||||
- name: Cache Maven Repository
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ~/.m2/repository
|
|
||||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-maven-
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
name: Build and Analyse
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
- feature*
|
||||||
|
pull_request:
|
||||||
|
types: [ opened, synchronize, reopened ]
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build-and-analyse:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||||
|
|
||||||
|
- name: Setup Java and Maven
|
||||||
|
uses: ./.gitea/actions/setup-java-maven
|
||||||
|
|
||||||
|
- name: Build and test
|
||||||
|
run: mvn -B verify
|
||||||
|
|
||||||
|
- name: Publish Test Report
|
||||||
|
uses: ./.gitea/actions/publish-report
|
||||||
|
if: ${{ always() }}
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
name: Publish JUnit Report (Short Names)
|
|
||||||
description: Normalize JUnit XML report names and publish a summary-only test report.
|
|
||||||
inputs:
|
|
||||||
token:
|
|
||||||
description: GitHub token for creating the check run.
|
|
||||||
required: true
|
|
||||||
report-name:
|
|
||||||
description: Name shown for the test report.
|
|
||||||
required: false
|
|
||||||
default: Summary of JUnit Tests
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: composite
|
|
||||||
steps:
|
|
||||||
- name: Normalize JUnit report names
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
mkdir -p junit-short
|
|
||||||
shopt -s globstar nullglob
|
|
||||||
for f in **/target/*-reports/TEST-*.xml; do
|
|
||||||
base="$(basename "$f")"
|
|
||||||
short="${base#TEST-}"
|
|
||||||
short="${short%.xml}"
|
|
||||||
cp "$f" "junit-short/${short}"
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Publish Test Report
|
|
||||||
uses: dorny/test-reporter@v2
|
|
||||||
with:
|
|
||||||
token: ${{ inputs.token }}
|
|
||||||
name: ${{ inputs.report-name }}
|
|
||||||
path: "*"
|
|
||||||
reporter: java-junit
|
|
||||||
only-summary: true
|
|
||||||
working-directory: "junit-short"
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
name: Build and Analyse
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- develop
|
|
||||||
- feature*
|
|
||||||
pull_request:
|
|
||||||
types: [ opened, synchronize, reopened ]
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
build-and-analyse:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
|
||||||
|
|
||||||
- name: Setup Java and Maven
|
|
||||||
uses: ./.github/actions/setup-java-maven
|
|
||||||
|
|
||||||
- name: Build and analyze with SonarCloud
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
||||||
CF_API_TOKEN: ${{ secrets.API_TOKEN }}
|
|
||||||
run: |
|
|
||||||
echo "Running SonarCloud analysis..."
|
|
||||||
mvn -B -DtestClasspath=src/test/ verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=th-schwarz_CloudflareDNS-java
|
|
||||||
|
|
||||||
- name: Publish Test Report
|
|
||||||
uses: ./.github/actions/publish-report/
|
|
||||||
if: ${{ always() }}
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
report-name: Summary of JUnit Tests
|
|
||||||
@@ -11,3 +11,4 @@
|
|||||||
/info.txt
|
/info.txt
|
||||||
cf.yml
|
cf.yml
|
||||||
/docs/apidocs/javadoc.sh
|
/docs/apidocs/javadoc.sh
|
||||||
|
/.claude/settings.local.json
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
|
|
||||||
when:
|
|
||||||
- event: push
|
|
||||||
branch: develop
|
|
||||||
|
|
||||||
steps:
|
|
||||||
# - name: hello
|
|
||||||
# image: alpine
|
|
||||||
# commands:
|
|
||||||
# - echo "Hello World!"
|
|
||||||
|
|
||||||
- name: maven verify
|
|
||||||
image: maven:3-amazoncorretto-17-alpine
|
|
||||||
commands:
|
|
||||||
- mvn -B verify
|
|
||||||
@@ -1,22 +1,12 @@
|
|||||||
# CloudflareDNS-java
|
# CloudflareDNS-java
|
||||||
|
|
||||||
[](https://ci.codeberg.org/repos/16522)
|
|
||||||
|
|
||||||
[](https://sonarcloud.io/summary/new_code?id=th-schwarz_CloudflareDNS-java)
|
|
||||||
[](https://sonarcloud.io/summary/new_code?id=th-schwarz_CloudflareDNS-java)
|
|
||||||
[](https://sonarcloud.io/summary/new_code?id=th-schwarz_CloudflareDNS-java)
|
|
||||||
[](https://sonarcloud.io/summary/new_code?id=th-schwarz_CloudflareDNS-java)
|
|
||||||
[](https://sonarcloud.io/summary/new_code?id=th-schwarz_CloudflareDNS-java)
|
|
||||||
|
|
||||||
[](https://codeberg.org/th-schwarz/CloudflareDNS-java)
|
|
||||||
|
|
||||||
## Preface
|
## Preface
|
||||||
|
|
||||||
This project provides a java client for minimalistic access to the Cloudflare API version 4, which is mainly used for
|
This project provides a java client for minimalistic access to the Cloudflare API version 4, which is mainly used for
|
||||||
managing DNS settings such as creating, updating and deleting DNS records.
|
managing DNS settings such as creating, updating and deleting DNS records.
|
||||||
|
|
||||||
If you encounter any bugs or find missing features, feel free to report them on
|
If you encounter any bugs or find missing features, feel free to report them on
|
||||||
the [Codeberg Issues page](https://codeberg.org/th-schwarz/CloudflareDNS-java/issues).
|
the [GitHub Issues page](https://github.com/th-schwarz/CloudflareDNS-java/issues).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -28,56 +18,11 @@ This guide comes without any warranty. Use at your own risk. The author is not r
|
|||||||
|
|
||||||
## Get It
|
## Get It
|
||||||
|
|
||||||
The project has its own maven repository. It can be added to the `pom.xml`:
|
The project has its own maven repository. Follow the instructions on the latest [package](https://git.mein-gateway.de/thischwa/-/packages/maven/codes.thischwa:cloudflaredns) to add the repository to your project.
|
||||||
|
|
||||||
```xml
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>gitea</id>
|
|
||||||
<url>https://codeberg.org/api/packages/th-schwarz/maven</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
```
|
|
||||||
|
|
||||||
The dependency is:
|
|
||||||
```xml
|
|
||||||
<dependency>
|
|
||||||
<groupId>codes.thischwa</groupId>
|
|
||||||
<artifactId>cloudflaredns</artifactId>
|
|
||||||
<version>[version]</version>
|
|
||||||
</dependency>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
- 0.4.0-SNAPSHOT:
|
See [changelog](changelog.md)
|
||||||
- **Breaking Change**: renamed `client.zone().record()` to `client.zone().getRecord()`
|
|
||||||
- Code quality improvements: Increasing test coverage
|
|
||||||
- 0.3.0:
|
|
||||||
- **Breaking Change**:
|
|
||||||
- **New Fluent API**: Changed the initialization of the client(`new CfDnsClientBuilder().withApiTokenAuth("your-api-token").build()`)
|
|
||||||
- Authentication with API token.
|
|
||||||
- 0.2.0:
|
|
||||||
- **Breaking Change**: `emptyResultThrowsException` default changed from `true` to `false`. Now applies to both
|
|
||||||
single and multiple result requests. Empty results will be returned by default without throwing exceptions.
|
|
||||||
- API method names refactored for consistency: `zoneListAll` → `zoneList`, `zoneInfo` → `zoneGet`, `sldListAll` →
|
|
||||||
`recordList`
|
|
||||||
- RecordEntity getter methods renamed for clarity: `getName()` → `getSld()`
|
|
||||||
- **New Fluent API**: Changed the initialization of the client(`new CfDnsClientBuilder().withApiTokenAuth("your-api-token").build()`) and added chainable method interface for more readable DNS operations (
|
|
||||||
`client.zone().record()...`)
|
|
||||||
- Code quality improvements: removed duplication in batch operations, improved type safety in HTTP methods,
|
|
||||||
optimized string concatenation, removed mutable setters from CfDnsClient
|
|
||||||
- Enhanced type validation in `RecordEntity.build()` with better error messages
|
|
||||||
- CfClient#recordList must return multiple RecordEntries
|
|
||||||
- add a missing source jar
|
|
||||||
- ResponseResultInfo#Errors: wrong object structure
|
|
||||||
- changing multiple records with put, post, patch and delete for dns-records
|
|
||||||
- 0.1.0:
|
|
||||||
- refactored / extended tests
|
|
||||||
- 0.1.0-beta.3:
|
|
||||||
- fixed json deserialization
|
|
||||||
- added logging of api errors
|
|
||||||
- 0.1.0-beta.1: 1st runnable version
|
|
||||||
|
|
||||||
## Methods Overview
|
## Methods Overview
|
||||||
|
|
||||||
@@ -92,7 +37,8 @@ The API provides two styles for working with DNS records:
|
|||||||
2. **Fluent API**: Chainable method calls for more readable code
|
2. **Fluent API**: Chainable method calls for more readable code
|
||||||
|
|
||||||
The following text focuses on the basic methods. For further information, take a look at
|
The following text focuses on the basic methods. For further information, take a look at
|
||||||
the [javadoc of the CfDnsClient](https://cloudflaredns-java-f4ee3a.gitlab.io/apidocs/codes/thischwa/cf/CfDnsClient.html).
|
the \
|
||||||
|
[](https://javadoc.mein-gateway.de/CloudflareDNS-java/index.html)
|
||||||
|
|
||||||
### Instantiation of `CfDnsClient`
|
### Instantiation of `CfDnsClient`
|
||||||
|
|
||||||
@@ -466,6 +412,3 @@ try {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Summary
|
|
||||||
|
|
||||||
`CfDnsClient` offers a simple interface for managing DNS entries via Cloudflare's public API, allowing seamless CRUD operations and automation-friendly workflows.
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
- 0.5.0-SNAPSHOT:
|
||||||
|
- moved the project to git.mein-gateway.de
|
||||||
|
- replaced sonarqube with own actions
|
||||||
|
- migrate to jackson 3.x
|
||||||
|
- 0.4.0:
|
||||||
|
- fixed some paging issues
|
||||||
|
- **Breaking Change**: renamed `client.zone().record()` to `client.zone().getRecord()`
|
||||||
|
- Code quality improvements: Increasing test coverage
|
||||||
|
- 0.3.0:
|
||||||
|
- **Breaking Change**:
|
||||||
|
- **New Fluent API**: Changed the initialization of the client(`new CfDnsClientBuilder().withApiTokenAuth("your-api-token").build()`)
|
||||||
|
- Authentication with API token.
|
||||||
|
- 0.2.0:
|
||||||
|
- **Breaking Change**: `emptyResultThrowsException` default changed from `true` to `false`. Now applies to both
|
||||||
|
single and multiple result requests. Empty results will be returned by default without throwing exceptions.
|
||||||
|
- API method names refactored for consistency: `zoneListAll` → `zoneList`, `zoneInfo` → `zoneGet`, `sldListAll` →
|
||||||
|
`recordList`
|
||||||
|
- RecordEntity getter methods renamed for clarity: `getName()` → `getSld()`
|
||||||
|
- **New Fluent API**: Changed the initialization of the client(`new CfDnsClientBuilder().withApiTokenAuth("your-api-token").build()`) and added chainable method interface for more readable DNS operations (
|
||||||
|
`client.zone().record()...`)
|
||||||
|
- Code quality improvements: removed duplication in batch operations, improved type safety in HTTP methods,
|
||||||
|
optimized string concatenation, removed mutable setters from CfDnsClient
|
||||||
|
- Enhanced type validation in `RecordEntity.build()` with better error messages
|
||||||
|
- CfClient#recordList must return multiple RecordEntries
|
||||||
|
- add a missing source jar
|
||||||
|
- ResponseResultInfo#Errors: wrong object structure
|
||||||
|
- changing multiple records with put, post, patch and delete for dns-records
|
||||||
|
- 0.1.0:
|
||||||
|
- refactored / extended tests
|
||||||
|
- 0.1.0-beta.3:
|
||||||
|
- fixed json deserialization
|
||||||
|
- added logging of api errors
|
||||||
|
- 0.1.0-beta.1: 1st runnable version
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB |
@@ -1,15 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Cloudflare DNS Client - java</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Cloudflare DNS Client - java</h1>
|
|
||||||
<p>A Java-based client for interacting with the Cloudflare DNS API.</p>
|
|
||||||
<p>
|
|
||||||
<a href="apidocs/index.html" target="_blank">View API Documentation</a>
|
|
||||||
</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -4,18 +4,20 @@
|
|||||||
|
|
||||||
<groupId>codes.thischwa</groupId>
|
<groupId>codes.thischwa</groupId>
|
||||||
<artifactId>cloudflaredns</artifactId>
|
<artifactId>cloudflaredns</artifactId>
|
||||||
<version>0.4.0</version>
|
<version>0.5.0-SNAPSHOT</version>
|
||||||
<name>CloudflareDNS-java</name>
|
<name>CloudflareDNS-java</name>
|
||||||
<inceptionYear>2025</inceptionYear>
|
<inceptionYear>2025</inceptionYear>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<issueManagement>
|
<issueManagement>
|
||||||
<url>https://codeberg.org/th-schwarz/CloudflareDNS-java/issues</url>
|
<url>https://github.com/th-schwarz/CloudflareDNS-java/issues</url>
|
||||||
<system>Codeberg Issues</system>
|
<system>GitHub Issues</system>
|
||||||
</issueManagement>
|
</issueManagement>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
<file.encoding>UTF-8</file.encoding>
|
<file.encoding>UTF-8</file.encoding>
|
||||||
<project.build.sourceEncoding>${file.encoding}</project.build.sourceEncoding>
|
<project.build.sourceEncoding>${file.encoding}</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>${file.encoding}</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>${file.encoding}</project.reporting.outputEncoding>
|
||||||
@@ -34,44 +36,34 @@
|
|||||||
<linkXRef>false</linkXRef>
|
<linkXRef>false</linkXRef>
|
||||||
|
|
||||||
<!-- 3rd party dependencies -->
|
<!-- 3rd party dependencies -->
|
||||||
<jackson.version>2.21.1</jackson.version>
|
<jackson.version>3.2.1</jackson.version>
|
||||||
<httpclient5.version>5.5.1</httpclient5.version>
|
<httpclient5.version>5.6.2</httpclient5.version>
|
||||||
<lombok.version>1.18.36</lombok.version>
|
<lombok.version>1.18.46</lombok.version>
|
||||||
<slf4j.version>2.0.17</slf4j.version>
|
<slf4j.version>2.0.18</slf4j.version>
|
||||||
<logback-classic.version>1.5.25</logback-classic.version>
|
<logback-classic.version>1.5.38</logback-classic.version>
|
||||||
<junit5.version>5.14.2</junit5.version>
|
<junit5.version>5.14.2</junit5.version>
|
||||||
<mockito-junit5.version>5.21.0</mockito-junit5.version>
|
<mockito-junit5.version>5.23.0</mockito-junit5.version>
|
||||||
|
|
||||||
<!-- sonarqube -->
|
|
||||||
<sonar.organization>th-schwarz</sonar.organization>
|
|
||||||
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
|
|
||||||
<sonar.sourceEncoding>${file.encoding}</sonar.sourceEncoding>
|
|
||||||
<sonar.projectKey>th-schwarz_CloudflareDNS-java</sonar.projectKey>
|
|
||||||
<sonar.projectName>CloudflareDNS-java</sonar.projectName>
|
|
||||||
<sonar.branch.name>develop</sonar.branch.name>
|
|
||||||
<sonar.test.exclusions>src/test/java/**/*</sonar.test.exclusions>
|
|
||||||
|
|
||||||
<lombok-maven-plugin.version>1.18.20.0</lombok-maven-plugin.version>
|
<lombok-maven-plugin.version>1.18.20.0</lombok-maven-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
<developerConnection>scm:git:git@codeberg.org:th-schwarz/CloudflareDNS-java.git</developerConnection>
|
<developerConnection>scm:git:https://git.mein-gateway.de/thischwa/CloudflareDNS-java.git</developerConnection>
|
||||||
<connection>scm:git:git@codeberg.org:th-schwarz/CloudflareDNS-java.git</connection>
|
<connection>scm:git:https://git.mein-gateway.de/thischwa/CloudflareDNS-java.git</connection>
|
||||||
<url>https://codeberg.org/th-schwarz/CloudflareDNS-java</url>
|
<url>https://git.mein-gateway.de/thischwa/CloudflareDNS-java</url>
|
||||||
<tag>v0.4.0</tag>
|
<tag>HEAD</tag>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
<repository>
|
<repository>
|
||||||
<id>codeberg-cloudflaredns</id>
|
<id>mygitea</id>
|
||||||
<url>https://codeberg.org/api/packages/th-schwarz/maven</url>
|
<url>https://git.mein-gateway.de/api/packages/thischwa/maven</url>
|
||||||
<releases>
|
<releases>
|
||||||
<enabled>true</enabled>
|
<enabled>true</enabled>
|
||||||
</releases>
|
</releases>
|
||||||
</repository>
|
</repository>
|
||||||
<snapshotRepository>
|
<snapshotRepository>
|
||||||
<id>codeberg-cloudflaredns</id>
|
<id>mygitea</id>
|
||||||
<url>https://codeberg.org/api/packages/th-schwarz/maven</url>
|
<url>https://git.mein-gateway.de/api/packages/thischwa/maven</url>
|
||||||
<snapshots>
|
<snapshots>
|
||||||
<enabled>true</enabled>
|
<enabled>true</enabled>
|
||||||
</snapshots>
|
</snapshots>
|
||||||
@@ -103,19 +95,14 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>tools.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>${jackson.version}</version>
|
<version>${jackson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
|
||||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
|
||||||
<version>${jackson.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains</groupId>
|
<groupId>org.jetbrains</groupId>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
<version>24.0.0</version>
|
<version>26.1.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -144,7 +131,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.13.0</version>
|
<version>3.14.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>${java.version}</source>
|
<source>${java.version}</source>
|
||||||
<target>${java.version}</target>
|
<target>${java.version}</target>
|
||||||
@@ -154,7 +141,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.11.2</version>
|
<version>3.12.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<failOnError>false</failOnError>
|
<failOnError>false</failOnError>
|
||||||
<failOnWarnings>false</failOnWarnings>
|
<failOnWarnings>false</failOnWarnings>
|
||||||
@@ -208,7 +195,7 @@
|
|||||||
<!-- generates the code coverage report for sonar cube -->
|
<!-- generates the code coverage report for sonar cube -->
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
<version>0.8.13</version>
|
<version>0.8.15</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>prepare-agent</id>
|
<id>prepare-agent</id>
|
||||||
@@ -233,7 +220,7 @@
|
|||||||
<!-- to export test summary -->
|
<!-- to export test summary -->
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.5.3</version>
|
<version>3.5.6</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -267,7 +254,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.5.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>attach-delomboked-sources</id>
|
<id>attach-delomboked-sources</id>
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Test Report
|
||||||
|
|
||||||
|
_Generated on 2026-08-05 15:43:07 UTC_
|
||||||
|
|
||||||
|
**✅ All tests passed**
|
||||||
|
|
||||||
|
## Test Results
|
||||||
|
|
||||||
|
| | Tests | Passed | Failed | Skipped |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| **Total** | 90 | 90 | 0 | 0 |
|
||||||
|
|
||||||
|
### Details
|
||||||
|
|
||||||
|
| Status | Suite | Tests | Passed | Failed | Skipped |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| ✅ | codes.thischwa.cf.CfBasicHttpClientTest | 9 | 9 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.CfClientPenTest | 0 | 0 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.CfClientTest | 0 | 0 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.CfDnsClientBuilderTest | 16 | 16 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.CfDnsClientMockTest | 16 | 16 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.CfRequestTest | 8 | 8 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.ObjectMapperTest | 2 | 2 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.ResponseValidatorTest | 8 | 8 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.fluent.FluentApiTest | 15 | 15 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.model.BatchEntryTest | 2 | 2 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.model.PagingRequestTest | 4 | 4 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.model.RecordEntityTest | 6 | 6 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.model.RecordTypeTest | 3 | 3 | 0 | 0 |
|
||||||
|
| ✅ | codes.thischwa.cf.model.ZoneEntityTest | 1 | 1 | 0 | 0 |
|
||||||
|
|
||||||
|
## Coverage
|
||||||
|
|
||||||
|
| Package | Line Coverage | Branch Coverage |
|
||||||
|
|---|---|---|
|
||||||
|
| codes.thischwa.cf.fluent | 100% (25/25) | 100% (4/4) |
|
||||||
|
| codes.thischwa.cf.model | 100% (93/93) | 90% (9/10) |
|
||||||
|
| codes.thischwa.cf | 89% (249/279) | 71% (51/72) |
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package codes.thischwa.cf;
|
package codes.thischwa.cf;
|
||||||
|
|
||||||
import codes.thischwa.cf.model.AbstractResponse;
|
import codes.thischwa.cf.model.AbstractResponse;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpDelete;
|
import org.apache.hc.client5.http.classic.methods.HttpDelete;
|
||||||
@@ -20,6 +18,8 @@ import org.apache.hc.core5.http.io.entity.EntityUtils;
|
|||||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
|
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import tools.jackson.core.JacksonException;
|
||||||
|
import tools.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for creating HTTP clients to interact with the Cloudflare API. Provides
|
* Abstract base class for creating HTTP clients to interact with the Cloudflare API. Provides
|
||||||
@@ -96,7 +96,7 @@ abstract class CfBasicHttpClient {
|
|||||||
throw new CloudflareApiException(
|
throw new CloudflareApiException(
|
||||||
request.getMethod() + " request failed with status code: " + result.statusCode);
|
request.getMethod() + " request failed with status code: " + result.statusCode);
|
||||||
}
|
}
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JacksonException e) {
|
||||||
log.error("JSON parsing error for request to {}", logUri, e);
|
log.error("JSON parsing error for request to {}", logUri, e);
|
||||||
throw new CloudflareApiException("Error processing JSON response", e);
|
throw new CloudflareApiException("Error processing JSON response", e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -182,7 +182,7 @@ abstract class CfBasicHttpClient {
|
|||||||
log.trace("Request methode [{}] payload: {}", request.getMethod(), jsonPayload);
|
log.trace("Request methode [{}] payload: {}", request.getMethod(), jsonPayload);
|
||||||
request.setEntity(new StringEntity(jsonPayload,
|
request.setEntity(new StringEntity(jsonPayload,
|
||||||
ContentType.APPLICATION_JSON));
|
ContentType.APPLICATION_JSON));
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JacksonException e) {
|
||||||
throw new CloudflareApiException("Error serializing JSON payload", e);
|
throw new CloudflareApiException("Error serializing JSON payload", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package codes.thischwa.cf;
|
package codes.thischwa.cf;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import tools.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import tools.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
import tools.jackson.databind.PropertyNamingStrategies;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import tools.jackson.databind.json.JsonMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JsonConf class provides a utility method for initializing and configuring a shared
|
* The JsonConf class provides a utility method for initializing and configuring a shared
|
||||||
@@ -16,11 +16,11 @@ class JsonConf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ObjectMapper initObjectMapper() {
|
static ObjectMapper initObjectMapper() {
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
return JsonMapper.builder()
|
||||||
mapper.registerModule(new JavaTimeModule());
|
.changeDefaultPropertyInclusion(
|
||||||
mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);
|
incl -> incl.withValueInclusion(JsonInclude.Include.NON_NULL))
|
||||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
|
||||||
mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
|
.propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
|
||||||
return mapper;
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,18 +11,18 @@ import codes.thischwa.cf.model.RecordMultipleResponse;
|
|||||||
import codes.thischwa.cf.model.RecordSingleResponse;
|
import codes.thischwa.cf.model.RecordSingleResponse;
|
||||||
import codes.thischwa.cf.model.ResponseResultInfo;
|
import codes.thischwa.cf.model.ResponseResultInfo;
|
||||||
import codes.thischwa.cf.model.ZoneMultipleResponse;
|
import codes.thischwa.cf.model.ZoneMultipleResponse;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import tools.jackson.core.JacksonException;
|
||||||
|
import tools.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
public class ObjectMapperTest {
|
public class ObjectMapperTest {
|
||||||
|
|
||||||
private final ObjectMapper mapper = JsonConf.initObjectMapper();
|
private final ObjectMapper mapper = JsonConf.initObjectMapper();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testObjectMapper() throws IOException {
|
void testObjectMapper() {
|
||||||
ZoneMultipleResponse resp =
|
ZoneMultipleResponse resp =
|
||||||
mapper.readValue(this.getClass().getResourceAsStream("/zone-list-response.json"),
|
mapper.readValue(this.getClass().getResourceAsStream("/zone-list-response.json"),
|
||||||
ZoneMultipleResponse.class);
|
ZoneMultipleResponse.class);
|
||||||
@@ -30,7 +30,7 @@ public class ObjectMapperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testErrorResponse() throws IOException {
|
void testErrorResponse() {
|
||||||
List<Class<? extends AbstractResponse>> respClasses =
|
List<Class<? extends AbstractResponse>> respClasses =
|
||||||
List.of(RecordSingleResponse.class, RecordMultipleResponse.class, ZoneMultipleResponse.class, BatchResponse.class);
|
List.of(RecordSingleResponse.class, RecordMultipleResponse.class, ZoneMultipleResponse.class, BatchResponse.class);
|
||||||
respClasses.forEach(this::assertErrorResponse);
|
respClasses.forEach(this::assertErrorResponse);
|
||||||
@@ -46,7 +46,7 @@ public class ObjectMapperTest {
|
|||||||
assertFalse(resultInfo.isSuccess());
|
assertFalse(resultInfo.isSuccess());
|
||||||
assertEquals(1, resultInfo.getErrors().size());
|
assertEquals(1, resultInfo.getErrors().size());
|
||||||
assertEquals(81053, resultInfo.getErrors().get(0).getCode());
|
assertEquals(81053, resultInfo.getErrors().get(0).getCode());
|
||||||
} catch (IOException e) {
|
} catch (JacksonException e) {
|
||||||
fail("fail for " + clazz + ": " + e.getMessage());
|
fail("fail for " + clazz + ": " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user