issue #9: Add recordList method to CfDnsClient, update Zone-level fluent API, and implement tests for DNS record listing with optional type filters.

This commit is contained in:
2026-01-06 20:14:05 +01:00
parent 483b79b372
commit acf2a2fc3b
5 changed files with 60 additions and 4 deletions
@@ -233,20 +233,38 @@ public class CfDnsClient extends CfBasicHttpClient {
public List<RecordEntity> recordGet(ZoneEntity zone, String sld, @Nullable RecordType... types)
throws CloudflareApiException {
String fqdn = buildFqdn(zone, sld);
String endpoint = buildEndpointWithTypeFilters(zone.getId(), fqdn, types);
String endpoint = buildEndpointWithTypeFilters(CfRequest.RECORD_INFO_NAME.buildPath(zone.getId(), fqdn), types);
RecordMultipleResponse resp = getRequest(endpoint, RecordMultipleResponse.class);
checkResponse(resp, false);
return resp.getResult();
}
private String buildEndpointWithTypeFilters(String zoneId, String fqdn, @Nullable RecordType... types) {
String baseEndpoint = CfRequest.RECORD_INFO_NAME.buildPath(zoneId, fqdn);
/**
* Retrieves a list of all DNS records for a given zone.
* Optionally filters by one or more DNS record types.
*
* @param zone The zone entity containing information about the domain zone.
* @param types Optional parameter specifying one or more DNS record types to filter the results.
* @return A list of {@code RecordEntity} objects representing the DNS records for the specified zone.
* @throws CloudflareApiException if an error occurs while interacting with the Cloudflare API
*/
public List<RecordEntity> recordList(ZoneEntity zone, RecordType... types)
throws CloudflareApiException {
String endpoint = buildEndpointWithTypeFilters(CfRequest.RECORD_LIST.buildPath(zone.getId()), types);
RecordMultipleResponse resp = getRequest(endpoint, RecordMultipleResponse.class);
checkResponse(resp, false);
return resp.getResult();
}
private String buildEndpointWithTypeFilters(String baseEndpoint, @Nullable RecordType... types) {
if (types == null || types.length == 0) {
return baseEndpoint;
}
StringBuilder endpoint = new StringBuilder(baseEndpoint);
String separator = baseEndpoint.contains("?") ? "&" : "?";
for (RecordType type : types) {
endpoint.append("&type=").append(type);
endpoint.append(separator).append("type=").append(type);
separator = "&";
}
return endpoint.toString();
}
@@ -20,6 +20,12 @@ public enum CfRequest {
*/
ZONE_INFO("/zones?name=%s"),
/**
* Represents the API endpoint path for retrieving information about DNS records within a
* specific DNS zone. The endpoint path includes a placeholder for the zone identifier, which
* needs to be provided to construct the complete path.
*/
RECORD_LIST("/zones/%s/dns_records"),
/**
* Represents the API endpoint path for creating a new DNS record within a specific DNS zone. The
* endpoint path includes a placeholder for the zone identifier, which needs to be provided to
@@ -28,4 +28,12 @@ public interface ZoneOperations {
* @throws CloudflareApiException if the zone cannot be found or accessed
*/
RecordOperations record(String sld, @Nullable RecordType... types) throws CloudflareApiException;
/**
* Lists all DNS records within the zone, optionally filtered by types.
*
* @param types optional DNS record types to filter by
* @return a list of RecordEntity objects matching the criteria
* @throws CloudflareApiException if an error occurs while retrieving records
*/
java.util.List<codes.thischwa.cf.model.RecordEntity> list(@Nullable RecordType... types) throws CloudflareApiException;
}
@@ -2,8 +2,10 @@ package codes.thischwa.cf.fluent;
import codes.thischwa.cf.CfDnsClient;
import codes.thischwa.cf.CloudflareApiException;
import codes.thischwa.cf.model.RecordEntity;
import codes.thischwa.cf.model.RecordType;
import codes.thischwa.cf.model.ZoneEntity;
import java.util.List;
import org.jetbrains.annotations.Nullable;
/**
@@ -34,4 +36,9 @@ public class ZoneOperationsImpl implements ZoneOperations {
public RecordOperations record(String sld, @Nullable RecordType... types) throws CloudflareApiException {
return new RecordOperationsImpl(client, zone, sld, types);
}
@Override
public List<RecordEntity> list(@Nullable RecordType... types) throws CloudflareApiException {
return client.recordList(zone, types);
}
}
@@ -153,6 +153,23 @@ public class CfClientTest {
}
}
// test recordList without SLD
List<RecordEntity> fullList = client.recordList(z);
assertTrue(fullList.size() >= 2);
assertTrue(fullList.stream().anyMatch(re -> re.getId().equals(createdRe1.getId())));
assertTrue(fullList.stream().anyMatch(re -> re.getId().equals(createdRe2.getId())));
// test recordList with types without SLD
List<RecordEntity> aList = client.recordList(z, RecordType.A);
assertTrue(aList.size() >= 1);
assertTrue(aList.stream().anyMatch(re -> re.getId().equals(createdRe1.getId())));
assertTrue(aList.stream().noneMatch(re -> re.getId().equals(createdRe2.getId())));
// test fluent api list
List<RecordEntity> fluentList = client.zone(ZONE_STR).list(RecordType.A);
assertTrue(fluentList.size() >= 1);
assertTrue(fluentList.stream().anyMatch(re -> re.getId().equals(createdRe1.getId())));
// update AAAA record
createdRe2.setContent("2a0a:4cc0:c0:2e4::2");
client.recordUpdate(z, createdRe2);