Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## 0.1.0 — Sin publicar

- Cambio incompatible: el cliente deja de registrar por defecto cada petición y
respuesta completas (`HttpLoggingInterceptor.Level.BODY`). El nuevo
`TuRuc.withLogLevel(Level)` activa el logging de OkHttp con el nivel indicado;
`logging-interceptor` pasa a ser dependencia `api`.
- Compatibilidad verificada con Java 17, 21 y 25; JDK 25 para compilar por defecto
y bytecode Java 17 para consumidores.
- Gradle 9.8.1 con wrapper regenerado y SHA-256 de distribución verificado.
Expand Down
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ var page = client.searchContribuyentes("NUÑEZ", 0).execute();
síncrona o `enqueue()` para una asíncrona.
- Crea el cliente una vez y reutilízalo; cada llamada a `getClient()` crea un
cliente HTTP nuevo.
- El cliente registra cada petición y respuesta completas, con su cuerpo, en el
log de OkHttp.

### Respuestas

Expand Down Expand Up @@ -97,6 +95,24 @@ completa. Para cambiarlos, indica los valores en segundos:
TuRucClient client = new TuRuc("https://turuc.com.py/", 30, 10, 10, 5).getClient();
```

### Logging

Por defecto, el cliente no registra el tráfico HTTP. Para depurar, indica un
nivel de `HttpLoggingInterceptor` de OkHttp:

```java
import okhttp3.logging.HttpLoggingInterceptor;

TuRucClient client = new TuRuc("https://turuc.com.py/")
.withLogLevel(HttpLoggingInterceptor.Level.BODY)
.getClient();
```

`BASIC` registra la petición y el estado de la respuesta; `HEADERS` agrega las
cabeceras; `BODY` también registra los cuerpos, con los datos de los
contribuyentes consultados. Los mensajes van al log de OkHttp
(`java.util.logging`, logger `okhttp3.OkHttpClient`).

## Migración desde 0.0.1-beta

La versión 0.1.0 cambia el modelo `Contribuyente` para reflejar la respuesta
Expand All @@ -122,6 +138,9 @@ si tu proyecto lo usa, decláralo por tu cuenta.

Las dependencias transitivas pasan a Retrofit 3.0.0 y OkHttp 5.5.0.

El cliente ya no registra las peticiones y respuestas completas. Si dependías de
esos logs, actívalos con `withLogLevel(HttpLoggingInterceptor.Level.BODY)`.

## Cambios

Consulta [CHANGELOG.md](CHANGELOG.md) para conocer los cambios de cada versión.
Expand Down
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ dependencies {

api(platform("com.squareup.okhttp3:okhttp-bom:5.5.0"))
implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okhttp3:logging-interceptor")
// HttpLoggingInterceptor.Level forma parte de la API pública (TuRuc.withLogLevel).
api("com.squareup.okhttp3:logging-interceptor")

testImplementation(platform("org.junit:junit-bom:6.1.3"))
testImplementation("org.junit.jupiter:junit-jupiter")
Expand Down
25 changes: 19 additions & 6 deletions src/main/java/org/ith/client/TuRuc.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.ith.client;

import com.alibaba.fastjson2.support.retrofit.Retrofit2ConverterFactory;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
Expand All @@ -15,6 +16,7 @@ public class TuRuc {
private final int writeTimeout;
private final int readTimeout;
private final int connectTimeout;
private HttpLoggingInterceptor.Level logLevel = HttpLoggingInterceptor.Level.NONE;

public TuRuc(String apiUrl) {
this.apiUrl = apiUrl;
Expand All @@ -32,17 +34,28 @@ public TuRuc(String apiUrl, int callTimeout, int writeTimeout, int readTimeout,
this.connectTimeout = connectTimeout;
}

/**
* Registra el tráfico HTTP en el log de OkHttp. Por defecto no se registra nada; {@code BODY} incluye los
* datos de los contribuyentes consultados.
*/
public TuRuc withLogLevel(HttpLoggingInterceptor.Level logLevel) {
this.logLevel = Objects.requireNonNull(logLevel, "logLevel");
return this;
}

public TuRucClient getClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
// Http Client
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.callTimeout(callTimeout, TimeUnit.SECONDS)
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
.readTimeout(readTimeout, TimeUnit.SECONDS)
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
.build();
.connectTimeout(connectTimeout, TimeUnit.SECONDS);
if (logLevel != HttpLoggingInterceptor.Level.NONE) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(logLevel);
builder.addInterceptor(interceptor);
}
OkHttpClient client = builder.build();
// Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(apiUrl)
Expand Down
72 changes: 71 additions & 1 deletion src/test/java/org/ith/client/TuRucClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import org.ith.model.Contribuyente;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -35,14 +42,45 @@ class TuRucClientTest {
@BeforeEach
void startServer() throws IOException {
server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0);
client = new TuRuc("http://127.0.0.1:" + server.getAddress().getPort() + "/", 5, 5, 5, 5).getClient();
client = new TuRuc(baseUrl(), 5, 5, 5, 5).getClient();
}

@AfterEach
void stopServer() {
server.stop(0);
}

@Test
void doesNotLogRequestsByDefault() throws Exception {
respond(200, """
{"data":{"doc":80024191,"ruc":"80024191-6"},"message":"OK"}
""");

var logs = captureOkHttpLogs(() -> client.getContribuyente("80024191-6").execute());

assertEquals(List.of(), logs);
}

@Test
void logsResponseBodyWhenRequested() throws Exception {
respond(200, """
{"data":{"doc":80024191,"ruc":"80024191-6"},"message":"OK"}
""");
var loggingClient = new TuRuc(baseUrl(), 5, 5, 5, 5)
.withLogLevel(HttpLoggingInterceptor.Level.BODY)
.getClient();

var logs = captureOkHttpLogs(
() -> loggingClient.getContribuyente("80024191-6").execute());

assertTrue(logs.stream().anyMatch(line -> line.contains("\"ruc\":\"80024191-6\"")), logs.toString());
}

@Test
void rejectsNullLogLevel() {
assertThrows(NullPointerException.class, () -> new TuRuc(baseUrl()).withLogLevel(null));
}

@Test
void looksUpContributorWithFullRuc() throws Exception {
respond(200, """
Expand Down Expand Up @@ -156,6 +194,38 @@ private Map<String, String> queryParameters(URI uri) {
pair -> URLDecoder.decode(pair[1], StandardCharsets.UTF_8)));
}

private String baseUrl() {
return "http://127.0.0.1:" + server.getAddress().getPort() + "/";
}

private interface Call {
void run() throws IOException;
}

private static List<String> captureOkHttpLogs(Call call) throws IOException {
var logger = Logger.getLogger(OkHttpClient.class.getName());
var lines = new ArrayList<String>();
var handler = new Handler() {
@Override
public void publish(LogRecord logRecord) {
lines.add(logRecord.getMessage());
}

@Override
public void flush() {}

@Override
public void close() {}
};
logger.addHandler(handler);
try {
call.run();
} finally {
logger.removeHandler(handler);
}
return lines;
}

private void respond(int status, String json) {
server.createContext("/", exchange -> {
requests.add(exchange.getRequestURI());
Expand Down
Loading