Refactor code for consistent formatting and style.

This commit is contained in:
2025-04-14 09:50:35 +02:00
parent 97b7f8371a
commit 16a586c080
8 changed files with 70 additions and 106 deletions
@@ -31,22 +31,19 @@ import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
* managing authentication, and handling JSON serialization. * managing authentication, and handling JSON serialization.
*/ */
@Slf4j @Slf4j
abstract class CfBasicHttpClient abstract class CfBasicHttpClient {
{
private final String baseUrl; private final String baseUrl;
private final String authEmail; private final String authEmail;
private final String authKey; private final String authKey;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
CfBasicHttpClient(String baseUrl, String authEmail, String authKey) throws IllegalArgumentException CfBasicHttpClient(String baseUrl, String authEmail, String authKey)
{ throws IllegalArgumentException {
if (authEmail == null || authEmail.isBlank()) if (authEmail == null || authEmail.isBlank()) {
{
throw new IllegalArgumentException("Authentication email must not be null or blank!"); throw new IllegalArgumentException("Authentication email must not be null or blank!");
} }
if (authKey == null || authKey.isBlank()) if (authKey == null || authKey.isBlank()) {
{
throw new IllegalArgumentException("Authentication key must not be null or blank!"); throw new IllegalArgumentException("Authentication key must not be null or blank!");
} }
this.baseUrl = baseUrl; this.baseUrl = baseUrl;
@@ -55,8 +52,7 @@ abstract class CfBasicHttpClient
this.objectMapper = initObjectMapper(); this.objectMapper = initObjectMapper();
} }
private ObjectMapper initObjectMapper() private ObjectMapper initObjectMapper() {
{
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule()); mapper.registerModule(new JavaTimeModule());
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
@@ -65,8 +61,7 @@ abstract class CfBasicHttpClient
return mapper; return mapper;
} }
private CloseableHttpClient createHttpClient() private CloseableHttpClient createHttpClient() {
{
return HttpClients.custom() return HttpClients.custom()
.addRequestInterceptorFirst( .addRequestInterceptorFirst(
(request, context, execChain) -> { (request, context, execChain) -> {
@@ -82,11 +77,9 @@ abstract class CfBasicHttpClient
} }
private <T extends AbstractResponse> T executeRequest( private <T extends AbstractResponse> T executeRequest(
ClassicHttpRequest request, Class<T> responseType) throws CloudflareApiException ClassicHttpRequest request, Class<T> responseType) throws CloudflareApiException {
{
String logUri = null; String logUri = null;
try (CloseableHttpClient client = createHttpClient()) try (CloseableHttpClient client = createHttpClient()) {
{
ResultWrapper result = ResultWrapper result =
client.execute( client.execute(
request, request,
@@ -96,11 +89,9 @@ abstract class CfBasicHttpClient
EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8))); EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8)));
logUri = request.getRequestUri(); logUri = request.getRequestUri();
if (result.statusCode >= 200 && result.statusCode < 300) if (result.statusCode >= 200 && result.statusCode < 300) {
{
return objectMapper.readValue(result.responseBody, responseType); return objectMapper.readValue(result.responseBody, responseType);
} else } else {
{
log.error( log.error(
"{} request failed for URL {}: Status {}", "{} request failed for URL {}: Status {}",
request.getMethod(), request.getMethod(),
@@ -109,93 +100,67 @@ 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 (JsonProcessingException 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) {
{
log.error("Error during request execution", e); log.error("Error during request execution", e);
throw new CloudflareApiException("Request failed", e); throw new CloudflareApiException("Request failed", e);
} }
} }
/** /** Sends a GET request to the given endpoint and maps the response. */
* Sends a GET request to the given endpoint and maps the response.
*/
<T extends AbstractResponse> T getRequest(String endpoint, Class<T> responseType) <T extends AbstractResponse> T getRequest(String endpoint, Class<T> responseType)
throws CloudflareApiException throws CloudflareApiException {
{
HttpGet request = new HttpGet(buildUrl(endpoint)); HttpGet request = new HttpGet(buildUrl(endpoint));
return executeRequest(request, responseType); return executeRequest(request, responseType);
} }
/** /** Sends a DELETE request to the given endpoint and maps the response. */
* Sends a DELETE request to the given endpoint and maps the response. <T extends AbstractResponse> T deleteRequest(String endpoint) throws CloudflareApiException {
*/
<T extends AbstractResponse> T deleteRequest(String endpoint)
throws CloudflareApiException
{
HttpDelete request = new HttpDelete(buildUrl(endpoint)); HttpDelete request = new HttpDelete(buildUrl(endpoint));
return executeRequest(request, (Class<T>) codes.thischwa.cf.model.RecordSingleResponse.class); return executeRequest(request, (Class<T>) codes.thischwa.cf.model.RecordSingleResponse.class);
} }
/** /** Sends a POST request with a payload to the given endpoint and maps the response. */
* Sends a POST request with a payload to the given endpoint and maps the response.
*/
<T extends AbstractResponse, R extends AbstractEntity> T postRequest( <T extends AbstractResponse, R extends AbstractEntity> T postRequest(
String endpoint, R requestPayload) throws CloudflareApiException String endpoint, R requestPayload) throws CloudflareApiException {
{
HttpPost request = new HttpPost(buildUrl(endpoint)); HttpPost request = new HttpPost(buildUrl(endpoint));
setRequestPayload(request, requestPayload); setRequestPayload(request, requestPayload);
return executeRequest(request, (Class<T>) codes.thischwa.cf.model.RecordSingleResponse.class); return executeRequest(request, (Class<T>) codes.thischwa.cf.model.RecordSingleResponse.class);
} }
/** /** Sends a PUT request with a payload to the given endpoint and maps the response. */
* Sends a PUT request with a payload to the given endpoint and maps the response.
*/
<T extends AbstractResponse, R extends AbstractEntity> T putRequest( <T extends AbstractResponse, R extends AbstractEntity> T putRequest(
String endpoint, R requestPayload, Class<T> responseType) throws CloudflareApiException String endpoint, R requestPayload, Class<T> responseType) throws CloudflareApiException {
{
HttpPut request = new HttpPut(buildUrl(endpoint)); HttpPut request = new HttpPut(buildUrl(endpoint));
setRequestPayload(request, requestPayload); setRequestPayload(request, requestPayload);
return executeRequest(request, responseType); return executeRequest(request, responseType);
} }
/** /** Sends a PATCH request with a payload to the given endpoint and maps the response. */
* Sends a PATCH request with a payload to the given endpoint and maps the response.
*/
<T extends AbstractResponse, R extends AbstractEntity> T patchRequest( <T extends AbstractResponse, R extends AbstractEntity> T patchRequest(
String endpoint, R requestPayload) throws CloudflareApiException String endpoint, R requestPayload) throws CloudflareApiException {
{
HttpPatch request = new HttpPatch(buildUrl(endpoint)); HttpPatch request = new HttpPatch(buildUrl(endpoint));
setRequestPayload(request, requestPayload); setRequestPayload(request, requestPayload);
return executeRequest(request, (Class<T>) codes.thischwa.cf.model.RecordSingleResponse.class); return executeRequest(request, (Class<T>) codes.thischwa.cf.model.RecordSingleResponse.class);
} }
/** /** Sets the JSON payload for a request. */
* Sets the JSON payload for a request.
*/
private <R extends AbstractEntity> void setRequestPayload( private <R extends AbstractEntity> void setRequestPayload(
BasicClassicHttpRequest request, R requestPayload) throws CloudflareApiException BasicClassicHttpRequest request, R requestPayload) throws CloudflareApiException {
{ try {
try
{
request.setEntity( request.setEntity(
new StringEntity( new StringEntity(
objectMapper.writeValueAsString(requestPayload), ContentType.APPLICATION_JSON)); objectMapper.writeValueAsString(requestPayload), ContentType.APPLICATION_JSON));
} catch (JsonProcessingException e) } catch (JsonProcessingException e) {
{
throw new CloudflareApiException("Error serializing JSON payload", e); throw new CloudflareApiException("Error serializing JSON payload", e);
} }
} }
private String buildUrl(String endpoint) private String buildUrl(String endpoint) {
{
return baseUrl + endpoint; return baseUrl + endpoint;
} }
private record ResultWrapper(int statusCode, String responseBody) private record ResultWrapper(int statusCode, String responseBody) {}
{
}
} }
@@ -82,10 +82,7 @@ public class CfDnsClient extends CfBasicHttpClient {
* @param authKey The API key for authenticating the client with Cloudflare services. * @param authKey The API key for authenticating the client with Cloudflare services.
*/ */
public CfDnsClient( public CfDnsClient(
boolean emptyResultThrowsException, boolean emptyResultThrowsException, String baseUrl, String authEmail, String authKey) {
String baseUrl,
String authEmail,
String authKey) {
super(baseUrl, authEmail, authKey); super(baseUrl, authEmail, authKey);
this.emptyResultThrowsException = emptyResultThrowsException; this.emptyResultThrowsException = emptyResultThrowsException;
} }
+20 -22
View File
@@ -9,46 +9,44 @@ import lombok.Getter;
@Getter @Getter
public enum CfRequest { public enum CfRequest {
/** /** Represents the API endpoint path for retrieving the list of DNS zones. */
* Represents the API endpoint path for retrieving the list of DNS zones.
*/
ZONE_LIST("/zones"), ZONE_LIST("/zones"),
/** /**
* Represents the API endpoint path for retrieving information about a specific DNS zone * Represents the API endpoint path for retrieving information about a specific DNS zone by its
* by its name. The endpoint path supports a placeholder for the zone name, which needs * name. The endpoint path supports a placeholder for the zone name, which needs to be provided to
* to be provided to construct the complete path. * construct the complete path.
*/ */
ZONE_INFO("/zones?name=%s"), ZONE_INFO("/zones?name=%s"),
/** /**
* Represents the API endpoint path for creating a new DNS record within a specific DNS zone. * Represents the API endpoint path for creating a new DNS record within a specific DNS zone. The
* The endpoint path includes a placeholder for the zone identifier, which needs to * endpoint path includes a placeholder for the zone identifier, which needs to be provided to
* be provided to construct the complete path. * construct the complete path.
*/ */
RECORD_CREATE("/zones/%s/dns_records"), RECORD_CREATE("/zones/%s/dns_records"),
/** /**
* Represents the API endpoint path for retrieving information about a DNS record within a specific * Represents the API endpoint path for retrieving information about a DNS record within a
* DNS zone by its name. The endpoint path includes placeholders for the zone identifier and * specific DNS zone by its name. The endpoint path includes placeholders for the zone identifier
* the record name, which need to be provided to construct the complete path. * and the record name, which need to be provided to construct the complete path.
*/ */
RECORD_INFO_NAME("/zones/%s/dns_records?name=%s"), RECORD_INFO_NAME("/zones/%s/dns_records?name=%s"),
/** /**
* Represents the API endpoint path for retrieving information about a DNS record within a specific * Represents the API endpoint path for retrieving information about a DNS record within a
* DNS zone by its name and type. * specific DNS zone by its name and type. The endpoint path includes placeholders for the zone
* The endpoint path includes placeholders for the zone identifier, record name, and record type, * identifier, record name, and record type, which need to be provided to construct the complete
* which need to be provided to construct the complete path. * path.
*/ */
RECORD_INFO_NAME_TYPE("/zones/%s/dns_records?name=%s&type=%s"), RECORD_INFO_NAME_TYPE("/zones/%s/dns_records?name=%s&type=%s"),
/** /**
* Represents the API endpoint path for updating an existing DNS record within a specific DNS zone. * Represents the API endpoint path for updating an existing DNS record within a specific DNS
* The endpoint path includes placeholders for the zone identifier and the record identifier, * zone. The endpoint path includes placeholders for the zone identifier and the record
* which need to be provided to construct the complete path. * identifier, which need to be provided to construct the complete path.
*/ */
RECORD_UPDATE("/zones/%s/dns_records/%s"), RECORD_UPDATE("/zones/%s/dns_records/%s"),
/** /**
* Represents the API endpoint path for deleting an existing DNS record within a specific DNS zone. * Represents the API endpoint path for deleting an existing DNS record within a specific DNS
* The endpoint path includes placeholders for the zone identifier and the record identifier, * zone. The endpoint path includes placeholders for the zone identifier and the record
* which need to be provided to construct the complete path. * identifier, which need to be provided to construct the complete path.
*/ */
RECORD_DELETE("/zones/%s/dns_records/%s"); RECORD_DELETE("/zones/%s/dns_records/%s");
@@ -21,8 +21,10 @@ public class CloudflareApiException extends Exception {
/** /**
* Constructs a new CloudflareApiException with the specified detail message and cause. * Constructs a new CloudflareApiException with the specified detail message and cause.
* *
* @param message the detail message, which provides additional context or information about the exception. * @param message the detail message, which provides additional context or information about the
* @param cause the cause of this exception, which is the underlying throwable that triggered this exception. * exception.
* @param cause the cause of this exception, which is the underlying throwable that triggered this
* exception.
*/ */
public CloudflareApiException(String message, Throwable cause) { public CloudflareApiException(String message, Throwable cause) {
super(message, cause); super(message, cause);
@@ -31,8 +33,8 @@ public class CloudflareApiException extends Exception {
/** /**
* Constructs a new CloudflareApiException with the specified cause. * Constructs a new CloudflareApiException with the specified cause.
* *
* @param cause the cause of this exception, which is the underlying throwable * @param cause the cause of this exception, which is the underlying throwable that triggered this
* that triggered this exception. * exception.
*/ */
public CloudflareApiException(Throwable cause) { public CloudflareApiException(Throwable cause) {
super(cause); super(cause);
@@ -12,8 +12,8 @@ public class CloudflareNotFoundException extends CloudflareApiException {
/** /**
* Constructs a new CloudflareNotFoundException with the specified detail message. * Constructs a new CloudflareNotFoundException with the specified detail message.
* *
* @param message the detail message, which provides additional context about the "not found" error * @param message the detail message, which provides additional context about the "not found"
* encountered during interaction with the Cloudflare API. * error encountered during interaction with the Cloudflare API.
*/ */
public CloudflareNotFoundException(String message) { public CloudflareNotFoundException(String message) {
super(message); super(message);
@@ -22,9 +22,10 @@ public class CloudflareNotFoundException extends CloudflareApiException {
/** /**
* Constructs a new CloudflareNotFoundException with the specified detail message and cause. * Constructs a new CloudflareNotFoundException with the specified detail message and cause.
* *
* @param message the detail message, which provides additional context about the "not found" error * @param message the detail message, which provides additional context about the "not found"
* encountered during interaction with the Cloudflare API. * error encountered during interaction with the Cloudflare API.
* @param cause the cause of this exception, which is the underlying throwable that triggered this exception. * @param cause the cause of this exception, which is the underlying throwable that triggered this
* exception.
*/ */
public CloudflareNotFoundException(String message, Throwable cause) { public CloudflareNotFoundException(String message, Throwable cause) {
super(message, cause); super(message, cause);
@@ -33,8 +34,8 @@ public class CloudflareNotFoundException extends CloudflareApiException {
/** /**
* Constructs a new CloudflareNotFoundException with the specified cause. * Constructs a new CloudflareNotFoundException with the specified cause.
* *
* @param cause the cause of this exception, which is the underlying throwable * @param cause the cause of this exception, which is the underlying throwable that triggered this
* that triggered this exception. * exception.
*/ */
public CloudflareNotFoundException(Throwable cause) { public CloudflareNotFoundException(Throwable cause) {
super(cause); super(cause);
@@ -40,10 +40,10 @@ public class RecordEntity extends AbstractEntity {
@Nullable private LocalDateTime createdOn; @Nullable private LocalDateTime createdOn;
/** /**
* Initializes a new instance of the RecordEntity class and invokes the parent constructor * Initializes a new instance of the RecordEntity class and invokes the parent constructor from
* from the AbstractEntity class. The RecordEntity class represents a DNS record entity * the AbstractEntity class. The RecordEntity class represents a DNS record entity within a
* within a specific zone, encapsulating attributes such as type, name, content, TTL, * specific zone, encapsulating attributes such as type, name, content, TTL, and other related
* and other related metadata. * metadata.
*/ */
public RecordEntity() { public RecordEntity() {
super(); super();
@@ -125,6 +125,7 @@ public enum RecordType {
* encrypted or signed email exchanges. * encrypted or signed email exchanges.
* *
* <p>Key features include: * <p>Key features include:
*
* <ul> * <ul>
* <li>Use in Secure/Multipurpose Internet Mail Extensions (S/MIME)-based messaging. * <li>Use in Secure/Multipurpose Internet Mail Extensions (S/MIME)-based messaging.
* <li>Facilitating secure email communications by publishing certificates in DNS. * <li>Facilitating secure email communications by publishing certificates in DNS.