Skip to content

Commit

Permalink
Możliwość określenia nagłówka Accept dla niektórych endpointów (stero…
Browse files Browse the repository at this point in the history
…wanie wersją typu wyniku zwracanego przez endpoint KSeF, np. `application/vnd.v3+json`)

- wyjątek `NoAuthenticationException` — dla błędu 21304 brak uwierzytelniania
- `NoAuthorizationException` - wyrzucany dla "21301 Brak autoryzacji" dziedziczy aktualnie po `NonRepeatableException`
  • Loading branch information
alapierre committed Nov 12, 2023
1 parent 41e7823 commit 7fc24cf
Show file tree
Hide file tree
Showing 16 changed files with 242 additions and 62 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
# KSeF java REST client

KSeF
- API version: 2.0.0
- Build date: 2023-08-31
- API version: 2.0.4
- Build date: 2023-11-12
- wspierana wersja schemy XML: FA (2)

Krajowy Systemu e-Faktur
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,14 @@ public UpoDTO getUpo(@NotNull String referenceNumber) throws ApiException {
.processingDescription(upo.getProcessingDescription())
.build();
}

public SessionStatusResponse sessionStatusWithUpoURL(@NotNull String referenceNumber) throws ApiException {
val endpoint = String.format("common/Status/%s", referenceNumber);
val resp = apiClient.getJsonWithAcceptHeader(endpoint, SessionStatusResponse.class, "application/vnd.v3+json");
return resp.orElseThrow(() -> new ApiException("Nieprawidłowa odpowiedź z API"));
}

public void loadUpoByUrl(String upoUrl, @NotNull OutputStream os) throws ApiException {
apiClient.getStream(upoUrl, "", os);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ public SessionStatus sessionStatusByReference(@NotNull String token, @NotNull St
return ret.orElseThrow(() -> new ApiException(BAD_API_RESPONSE));
}

@NotNull
public SessionStatus sessionStatusByReference(@NotNull String token, @NotNull String reference, int pageSize, int pageOffset, boolean details) throws ApiException {

val endpoint= String.format("online/Session/Status/%s?PageSize=%d&PageOffset=%d&IncludeDetails=%b", reference, pageSize, pageOffset, details);

val ret = apiClient.getJson(endpoint, SessionStatus.class, token);
return ret.orElseThrow(() -> new ApiException(BAD_API_RESPONSE));
}

@NotNull
public SessionTerminateResponse terminateSession(@NotNull String token) throws ApiException {
val ret = apiClient.getJson("online/Session/Terminate", SessionTerminateResponse.class, token);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.alapierre.ksef.client.model.rest.invoice;

import lombok.Data;

/**
* @author Adrian Lapierre {@literal [email protected]}
* Copyrights by original author 2022.01.22
*/
@Data
public class SessionStatusResponse {
private String timestamp;
private String referenceNumber;
private int processingCode;
private String processingDescription;
private String upoUrl;
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ public <R> Optional<R> getJson(@NotNull String endpoint, @NotNull Class<R> class
return callAndReturnJson(classOfR, request);
}

@Override
public <R> Optional<R> getJsonWithAcceptHeader(@NotNull String endpoint, @NotNull Class<R> classOfR, @NotNull String accept) throws ApiException {
HttpRequest request = prepareGetRequest(endpoint, Map.of("Accept", accept));
return callAndReturnJson(classOfR, request);
}

@Override
public <B, R> Optional<R> postJson(@NotNull String endpoint, @NotNull B body, @NotNull Class<R> classOfR) throws ApiException {
HttpRequest request = preparePostRequest(endpoint, Collections.emptyMap(), HttpRequest.BodyPublishers.ofString(serializer.toJson(body)), true);
Expand All @@ -60,6 +66,12 @@ public <B, R> Optional<R> postJson(@NotNull String endpoint, @NotNull B body, @N
return callAndReturnJson(classOfR, request);
}

@Override
public <R> Optional<R> getJson(@NotNull String endpoint, @NotNull Class<R> classOfR, @NotNull String token, @NotNull String accept) throws ApiException {
HttpRequest request = prepareGetRequest(endpoint, Map.of("Accept", accept));
return callAndReturnJson(classOfR, request);
}

@Override
public <B, R> Optional<R> putJson(@NotNull String endpoint, @NotNull B body, @NotNull Class<R> classOfR, @NotNull String token) throws ApiException {
HttpRequest request = preparePostRequest(endpoint, Map.of(TOKEN_HEADER_NAME, token), HttpRequest.BodyPublishers.ofString(serializer.toJson(body)), false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,33 @@ public OkHttpApiClient(JsonSerializer serializer, Environment environment, OkHtt

@Override
public <R> Optional<R> getJson(@NotNull String endpoint, @NotNull Class<R> classOfR, @NotNull String token) throws ApiException {
return getJson(endpoint, classOfR, token, "application/json");
}

@Override
public <R> Optional<R> getJson(@NotNull String endpoint, @NotNull Class<R> classOfR, @NotNull String token, @NotNull String accept) throws ApiException {

val builder = new Request.Builder();
builder.url(createUrl(endpoint));
builder.addHeader(TOKEN_HEADER_NAME, token);
builder
.addHeader(TOKEN_HEADER_NAME, token)
.addHeader("Accept", accept);
builder.get();

return callAndReturnJson(classOfR, builder.build());
}

@Override
public <R> Optional<R> getJsonWithAcceptHeader(@NotNull String endpoint, @NotNull Class<R> classOfR, @NotNull String accept) throws ApiException {

val builder = new Request.Builder();
builder.url(createUrl(endpoint))
.addHeader("Accept", accept)
.get();

return callAndReturnJson(classOfR, builder.build());
}

@Override
public <R> Optional<R> getJson(@NotNull String endpoint, @NotNull Class<R> classOfR) throws ApiException {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
import org.jetbrains.annotations.Nullable;

import java.io.ByteArrayOutputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -91,7 +88,8 @@ protected ApiException mapHttpResponseStatusToException(int code, String message
else if (code == 400) {

if(errorCodes.contains(21177)) return new MaxResultsExceededException(code, message, headers, body, exceptionsFromKSef);
if(errorCodes.contains(21301)) return new NoAuthorizationException(code, message, headers, body, exceptionsFromKSef);
if(errorCodes.contains(21301)) return new NoAuthorizationException(message, code, headers, body);
if(errorCodes.contains(21304)) return new NoAuthenticationException(code, message, headers, body, exceptionsFromKSef);

return new BadRequestException(code, message, headers, body, exceptionsFromKSef);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ public interface ApiClient {

<R> Optional<R> getJson(@NotNull String endpoint, @NotNull Class<R> classOfR) throws ApiException;

<R> Optional<R> getJsonWithAcceptHeader(@NotNull String endpoint, @NotNull Class<R> classOfR, @NotNull String accept) throws ApiException;

<B, R> Optional<R> postJson(@NotNull String endpoint, @NotNull B body, @NotNull Class<R> classOfR) throws ApiException;

<B, R> Optional<R> postJson(@NotNull String endpoint, @NotNull B body, @NotNull Class<R> classOfR, @NotNull String token) throws ApiException;

<R> Optional<R> getJson(@NotNull String endpoint, @NotNull Class<R> classOfR, @NotNull String token, @NotNull String accept) throws ApiException;

<B, R> Optional<R> putJson(@NotNull String endpoint, @NotNull B body, @NotNull Class<R> classOfR, @NotNull String token) throws ApiException;

<R> Optional<R> postXMLFromBytes(@NotNull String endpoint, byte[] body, @NotNull Class<R> classOfR) throws ApiException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package io.alapierre.ksef.client.exception;

import io.alapierre.ksef.client.ApiException;

import java.util.List;
import java.util.Map;

/**
* @author Adrian Lapierre {@literal [email protected]}
* Copyrights by original author 2023.10.23
*/
public class NoAuthenticationException extends ApiException {

public NoAuthenticationException() {
}

public NoAuthenticationException(Throwable throwable) {
super(throwable);
}

public NoAuthenticationException(String message) {
super(message);
}

public NoAuthenticationException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders, String responseBody, List<ExceptionDetail> details) {
super(message, throwable, code, responseHeaders, responseBody, details);
}

public NoAuthenticationException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders, String responseBody) {
super(message, throwable, code, responseHeaders, responseBody);
}

public NoAuthenticationException(String message, int code, Map<String, List<String>> responseHeaders, String responseBody) {
super(message, code, responseHeaders, responseBody);
}

public NoAuthenticationException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders) {
super(message, throwable, code, responseHeaders);
}

public NoAuthenticationException(int code, Map<String, List<String>> responseHeaders, String responseBody) {
super(code, responseHeaders, responseBody);
}

public NoAuthenticationException(int code, String message) {
super(code, message);
}

public NoAuthenticationException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody, List<ExceptionDetail> details) {
super(code, message, responseHeaders, responseBody, details);
}

public NoAuthenticationException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody) {
super(code, message, responseHeaders, responseBody);
}

public NoAuthenticationException(String message, Throwable throwable) {
super(message, throwable);
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,13 @@
package io.alapierre.ksef.client.exception;

import io.alapierre.ksef.client.ApiException;

import java.util.List;
import java.util.Map;

/**
* @author Adrian Lapierre {@literal [email protected]}
* Copyrights by original author 2023.10.23
*/
public class NoAuthorizationException extends ApiException {

public NoAuthorizationException() {
}

public NoAuthorizationException(Throwable throwable) {
super(throwable);
}

public NoAuthorizationException(String message) {
super(message);
}
public class NoAuthorizationException extends NonRepeatableException {

public NoAuthorizationException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders, String responseBody, List<ExceptionDetail> details) {
super(message, throwable, code, responseHeaders, responseBody, details);
Expand All @@ -34,27 +21,7 @@ public NoAuthorizationException(String message, int code, Map<String, List<Strin
super(message, code, responseHeaders, responseBody);
}

public NoAuthorizationException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders) {
super(message, throwable, code, responseHeaders);
}

public NoAuthorizationException(int code, Map<String, List<String>> responseHeaders, String responseBody) {
super(code, responseHeaders, responseBody);
}

public NoAuthorizationException(int code, String message) {
super(code, message);
}

public NoAuthorizationException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody, List<ExceptionDetail> details) {
super(code, message, responseHeaders, responseBody, details);
}

public NoAuthorizationException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody) {
super(code, message, responseHeaders, responseBody);
}

public NoAuthorizationException(String message, Throwable throwable) {
super(message, throwable);
}
}
32 changes: 16 additions & 16 deletions ksef-sample/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,22 @@
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<testSourceDirectory>src/test-integration/java</testSourceDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-failsafe-plugin</artifactId>-->
<!-- <version>3.1.2</version>-->
<!-- <configuration>-->
<!-- <testSourceDirectory>src/test-integration/java</testSourceDirectory>-->
<!-- </configuration>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <goals>-->
<!-- <goal>integration-test</goal>-->
<!-- <goal>verify</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
</plugins>
</build>

Expand Down
8 changes: 5 additions & 3 deletions ksef-sample/src/main/java/io/alapierre/ksef/sample/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ public static void main(String[] args) {

try {
val signedResponse = loginByToken();

System.out.println("session token = " + signedResponse.getSessionToken().getToken());

val invoiceApi = new InterfejsyInteraktywneFakturaApi(client);
val sessionToken = signedResponse.getSessionToken().getToken();

val sessionStatus = sesjaApi.sessionStatus(sessionToken, 10, 0);
System.out.println(sessionStatus);

val resp = invoiceApi.invoiceSend(new File("ksef-sample/src/main/resources/FA2.xml"), sessionToken);

System.out.printf("ElementReferenceNumber %s, ReferenceNumber %s, ProcessingCode %d\n",
Expand All @@ -65,9 +67,9 @@ public static void main(String[] args) {

sesjaApi.terminateSession(sessionToken);
} catch (ApiException ex) {
System.out.printf("Błąd wywołania API %d (%s) opis błędu %s", ex.getCode(), ex.getMessage(), ex.getResponseBody());
System.err.printf("Błąd wywołania API %d (%s) opis błędu %s", ex.getCode(), ex.getMessage(), ex.getResponseBody());
} catch (Exception e) {
System.out.println(e.getMessage());
System.err.println(e.getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.alapierre.ksef.test;

import io.alapierre.ksef.client.AbstractApiClient;
import io.alapierre.ksef.client.ApiClient;
import io.alapierre.ksef.client.ApiException;
import io.alapierre.ksef.client.JsonSerializer;
import io.alapierre.ksef.client.api.InterfejsyInteraktywneFakturaApi;
import io.alapierre.ksef.client.api.InterfejsyInteraktywneSesjaApi;
import io.alapierre.ksef.client.model.rest.auth.AuthorisationChallengeRequest;
import io.alapierre.ksef.client.model.rest.auth.InitSignedResponse;
import io.alapierre.ksef.client.model.rest.auth.SessionTerminateResponse;
import io.alapierre.ksef.client.okhttp.OkHttpApiClient;
import io.alapierre.ksef.client.serializer.gson.GsonJsonSerializer;
import io.alapierre.ksef.token.facade.KsefTokenFacade;
import lombok.val;
import org.jetbrains.annotations.NotNull;

import java.text.ParseException;

import static io.alapierre.ksef.test.TestConfig.NIP;
import static io.alapierre.ksef.test.TestConfig.TOKEN;

/**
* @author Adrian Lapierre {@literal [email protected]}
* Copyrights by original author 2023.11.07
*/
public abstract class BaseIT {

protected final JsonSerializer serializer = new GsonJsonSerializer();
protected final ApiClient client = new OkHttpApiClient(serializer);
protected final InterfejsyInteraktywneSesjaApi sessionApi = new InterfejsyInteraktywneSesjaApi(client);
protected final InterfejsyInteraktywneFakturaApi invoiceApi = new InterfejsyInteraktywneFakturaApi(client);

protected @NotNull InitSignedResponse login() throws ParseException, ApiException {
val facade = new KsefTokenFacade(sessionApi);
return facade.authByToken(AbstractApiClient.Environment.TEST, NIP, AuthorisationChallengeRequest.IdentifierType.onip, TOKEN);
}

protected @NotNull SessionTerminateResponse logout(String sessionToken) throws ApiException {
return sessionApi.terminateSession(sessionToken);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
*/
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Slf4j
public class RequestsTests {
public class RequestsIT {

JsonSerializer serializer = new GsonJsonSerializer();
ApiClient client = new OkHttpApiClient(serializer);
Expand Down
Loading

0 comments on commit 7fc24cf

Please sign in to comment.