finalize 1.3.4
This commit is contained in:
parent
1b31712ac7
commit
113ddb8a9f
8 changed files with 89 additions and 201 deletions
|
|
@ -85,7 +85,7 @@ public class KSeFAPIService {
|
||||||
// First open an interactive Session. The KSeFAuthManager automatically reuses
|
// First open an interactive Session. The KSeFAuthManager automatically reuses
|
||||||
// an existing session
|
// an existing session
|
||||||
|
|
||||||
// kseFAuthManager.openSession();
|
kseFAuthManager.openSession();
|
||||||
|
|
||||||
if (kseFAuthManager.getAccessToken() == null) {
|
if (kseFAuthManager.getAccessToken() == null) {
|
||||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
|
|
@ -219,6 +219,7 @@ public class KSeFAPIService {
|
||||||
textlist.add(referenceNumber);
|
textlist.add(referenceNumber);
|
||||||
fileData.setAttribute("ksef.referenceNumber", textlist);
|
fileData.setAttribute("ksef.referenceNumber", textlist);
|
||||||
|
|
||||||
|
kseFAuthManager.closeSession();
|
||||||
return referenceNumber;
|
return referenceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ public class KSeFAuthManager {
|
||||||
this.redeemToken();
|
this.redeemToken();
|
||||||
this.openInteractiveSession();
|
this.openInteractiveSession();
|
||||||
} else {
|
} else {
|
||||||
logger.info("│ ├── reuse existing KSeF Session...");
|
logger.warning("│ ├── ! Session already exists - reuse existing KSeF Session...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,43 +215,41 @@ public class KSeFAuthManager {
|
||||||
*/
|
*/
|
||||||
public boolean hasValidSession() {
|
public boolean hasValidSession() {
|
||||||
|
|
||||||
|
// Check if session reference number exists
|
||||||
|
if (sessionRefNumber == null || sessionRefNumber.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// // Check if session reference number exists
|
// Check if valid until timestamp exists
|
||||||
// if (sessionRefNumber == null || sessionRefNumber.isEmpty()) {
|
if (sessionValidUntil == null || sessionValidUntil.isEmpty()) {
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // Check if valid until timestamp exists
|
try {
|
||||||
// if (sessionValidUntil == null || sessionValidUntil.isEmpty()) {
|
// Parse the validUntil timestamp (ISO 8601 format with UTC)
|
||||||
// return false;
|
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
|
||||||
// }
|
Instant validUntilInstant = Instant.from(formatter.parse(sessionValidUntil));
|
||||||
|
|
||||||
// try {
|
// Get current time in UTC
|
||||||
// // Parse the validUntil timestamp (ISO 8601 format with UTC)
|
Instant now = Instant.now();
|
||||||
// DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
|
|
||||||
// Instant validUntilInstant = Instant.from(formatter.parse(sessionValidUntil));
|
|
||||||
|
|
||||||
// // Get current time in UTC
|
// Check if session is still valid
|
||||||
// Instant now = Instant.now();
|
boolean isValid = now.isBefore(validUntilInstant);
|
||||||
|
|
||||||
// // Check if session is still valid
|
if (debug && isValid) {
|
||||||
// boolean isValid = now.isBefore(validUntilInstant);
|
logger.info("├── Session is still valid until: " + sessionValidUntil);
|
||||||
|
} else if (debug) {
|
||||||
|
logger.info("├── Session expired at: " + sessionValidUntil);
|
||||||
|
}
|
||||||
|
|
||||||
// if (debug && isValid) {
|
return isValid;
|
||||||
// logger.info("├── Session is still valid until: " + sessionValidUntil);
|
|
||||||
// } else if (debug) {
|
|
||||||
// logger.info("├── Session expired at: " + sessionValidUntil);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return isValid;
|
} catch (Exception e) {
|
||||||
|
// If parsing fails, assume session is invalid
|
||||||
// } catch (Exception e) {
|
logger.warning("├── ⚠️ Error parsing sessionValidUntil timestamp: " +
|
||||||
// // If parsing fails, assume session is invalid
|
e.getMessage());
|
||||||
// logger.warning("├── ⚠️ Error parsing sessionValidUntil timestamp: " +
|
return false;
|
||||||
// e.getMessage());
|
}
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -771,4 +769,51 @@ public class KSeFAuthManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method closes the current session
|
||||||
|
*
|
||||||
|
* https://ksef-test.mf.gov.pl/docs/v2/index.html#tag/Wysylka-interaktywna/paths/~1api~1v2~1sessions~1online~1%7BreferenceNumber%7D~1invoices/post
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: Seems to be not possible to close a session in test - response is
|
||||||
|
* usually 400
|
||||||
|
*
|
||||||
|
* @throws PluginException
|
||||||
|
*/
|
||||||
|
public void closeSession() throws PluginException {
|
||||||
|
logger.info("├── 📦 KSeF API close session...");
|
||||||
|
// https://ksef-test.mf.gov.pl/api/v2/sessions/online/{referenceNumber}/close
|
||||||
|
String uri = baseURI + "/sessions/online/" + sessionRefNumber + "/close";
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
logger.info("│ ├── Endpoint: " + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sessionRefNumber == null || sessionRefNumber.isEmpty()) {
|
||||||
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
|
"API Error: Unable to close session - session does not exist!");
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse<String> response = null;
|
||||||
|
try {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(URI.create(uri))
|
||||||
|
.header("Accept", "application/json")
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
|
.POST(HttpRequest.BodyPublishers.noBody()) //
|
||||||
|
.build();
|
||||||
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
|
"API Error: Unable to request auth status: " + e.getMessage());
|
||||||
|
}
|
||||||
|
if (true) {
|
||||||
|
logger.info("│ ├── Response Code = " + response.statusCode());
|
||||||
|
logger.info("Response: " + response.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionRefNumber = null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import java.util.logging.Logger;
|
||||||
import org.imixs.workflow.FileData;
|
import org.imixs.workflow.FileData;
|
||||||
import org.imixs.workflow.ItemCollection;
|
import org.imixs.workflow.ItemCollection;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
import org.junit.jupiter.api.Order;
|
import org.junit.jupiter.api.Order;
|
||||||
|
|
@ -23,6 +24,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import com.alexanderlogistics.TestLoggerConfig;
|
import com.alexanderlogistics.TestLoggerConfig;
|
||||||
|
|
||||||
|
@Disabled
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
public class KSeFAPIServiceTest {
|
public class KSeFAPIServiceTest {
|
||||||
|
|
@ -49,9 +51,9 @@ public class KSeFAPIServiceTest {
|
||||||
manager.init();
|
manager.init();
|
||||||
|
|
||||||
// Open Session
|
// Open Session
|
||||||
manager.openSession();
|
// manager.openSession();
|
||||||
|
|
||||||
manager.checkTokenStatus();
|
// manager.checkTokenStatus();
|
||||||
// manager.loadPublicKeyCertificates();
|
// manager.loadPublicKeyCertificates();
|
||||||
// manager.authChallenge();
|
// manager.authChallenge();
|
||||||
// manager.authKSeFToken();
|
// manager.authKSeFToken();
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import javax.crypto.spec.IvParameterSpec;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
import org.junit.jupiter.api.Order;
|
import org.junit.jupiter.api.Order;
|
||||||
|
|
@ -26,6 +27,7 @@ import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
@Disabled
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
public class KSeFAuthManagerTest {
|
public class KSeFAuthManagerTest {
|
||||||
|
|
|
||||||
|
|
@ -1,165 +0,0 @@
|
||||||
package com.alexanderlogistics.ksef;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import org.imixs.workflow.exceptions.ModelException;
|
|
||||||
import org.imixs.workflow.exceptions.PluginException;
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.DisplayName;
|
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
|
||||||
import org.junit.jupiter.api.Order;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test cases KSeF Interface
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author rsoika
|
|
||||||
*/
|
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
|
||||||
public class TestKSeF {
|
|
||||||
|
|
||||||
final static String ENCODING = "UTF-8";
|
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(TestKSeF.class.getName());
|
|
||||||
|
|
||||||
// Configuration - replace with your actual values
|
|
||||||
private static final String KSEF_TEST_URL = "https://ksef-test.mf.gov.pl/api/v2";
|
|
||||||
// https://ksef-test.mf.gov.pl/api/v2/auth/challenge
|
|
||||||
|
|
||||||
private static HttpClient httpClient;
|
|
||||||
private static String challenge; // Static variable to share between tests
|
|
||||||
|
|
||||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
|
|
||||||
private String refNumber = null;
|
|
||||||
private String authToken = null;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setupClass() {
|
|
||||||
logger.info("=== KSeF 2.0 Client Test ===");
|
|
||||||
logger.info("KSeF URL: " + KSEF_TEST_URL);
|
|
||||||
logger.info("NIP: " + Params.NIP);
|
|
||||||
|
|
||||||
httpClient = HttpClient.newBuilder()
|
|
||||||
.version(HttpClient.Version.HTTP_2)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setup() throws PluginException, ModelException {
|
|
||||||
logger.info("setup test environment ...");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Order(1)
|
|
||||||
@DisplayName("Einfacher Challenge test 2.0 API")
|
|
||||||
public void testChallenge() throws Exception {
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(KSEF_TEST_URL + "/auth/challenge")) // nur Endpoint checken
|
|
||||||
.header("Accept", "application/json")
|
|
||||||
.POST(HttpRequest.BodyPublishers.noBody()) //
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
System.out.println("Status: " + response.statusCode());
|
|
||||||
System.out.println("Response: " + response.body());
|
|
||||||
|
|
||||||
// Prüfen, dass wir eine API-Antwort bekommen, kein HTML
|
|
||||||
assertTrue(response.statusCode() < 500, "API sollte antworten, Status < 500");
|
|
||||||
assertFalse(response.body().contains("<html>"), "Response sollte keine HTML-Seite sein");
|
|
||||||
|
|
||||||
// Challenge aus Response extrahieren und speichern
|
|
||||||
if (response.statusCode() == 200) {
|
|
||||||
JsonNode jsonNode = objectMapper.readTree(response.body());
|
|
||||||
challenge = jsonNode.get("challenge").asText();
|
|
||||||
logger.info("Extracted challenge: " + challenge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Order(2)
|
|
||||||
@DisplayName("KSeF Token Request")
|
|
||||||
public void testKsefToken() throws Exception {
|
|
||||||
// JSON Payload erstellen
|
|
||||||
|
|
||||||
String jsonPayload = String.format(
|
|
||||||
"{" +
|
|
||||||
"\"challenge\": \"%s\"," +
|
|
||||||
"\"contextIdentifier\": {" +
|
|
||||||
" \"type\": \"Nip\"," +
|
|
||||||
" \"value\": \"%s\"" +
|
|
||||||
"}," +
|
|
||||||
"\"encryptedToken\": \"%s\"" +
|
|
||||||
"}",
|
|
||||||
challenge, Params.NIP, Params.getEncodedToken());
|
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(KSEF_TEST_URL + "/auth/ksef-token"))
|
|
||||||
.header("Accept", "application/json")
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
System.out.println("Status: " + response.statusCode());
|
|
||||||
System.out.println("Response: " + response.body());
|
|
||||||
|
|
||||||
// Prüfen, dass wir eine API-Antwort bekommen
|
|
||||||
assertTrue(response.statusCode() < 500, "API sollte antworten, Status < 500");
|
|
||||||
assertFalse(response.body().contains("<html>"), "Response sollte keine HTML-Seite sein");
|
|
||||||
|
|
||||||
// JSON parsen und Werte speichern
|
|
||||||
if (response.statusCode() == 200 || response.statusCode() == 202) {
|
|
||||||
JsonNode jsonNode = objectMapper.readTree(response.body());
|
|
||||||
|
|
||||||
// Reference Number speichern
|
|
||||||
refNumber = jsonNode.get("referenceNumber").asText();
|
|
||||||
logger.info("Extracted referenceNumber: " + refNumber);
|
|
||||||
|
|
||||||
// Authentication Token speichern
|
|
||||||
authToken = jsonNode.get("authenticationToken").get("token").asText();
|
|
||||||
logger.info("Extracted authenticationToken: " + authToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Order(3)
|
|
||||||
@DisplayName("KSeF Public Key Zertifikate abrufen")
|
|
||||||
public void testFetchKsefPublicKeys() throws Exception {
|
|
||||||
assertNotNull(Params.TOKEN, "KSEF_TOKEN environment variable nicht gesetzt");
|
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(KSEF_TEST_URL + "/security/public-key-certificates"))
|
|
||||||
.header("Accept", "application/json")
|
|
||||||
.header("Authorization", "Bearer " + Params.TOKEN) // Access Token nutzen
|
|
||||||
.GET()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
System.out.println("Status: " + response.statusCode());
|
|
||||||
System.out.println("Response: " + response.body());
|
|
||||||
|
|
||||||
// Assertions
|
|
||||||
assertEquals(200, response.statusCode(), "Request sollte 200 OK zurückgeben");
|
|
||||||
assertTrue(response.body().contains("certificate"), "Response sollte ein Feld 'certificate' enthalten");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -8,6 +8,7 @@ import java.util.logging.Logger;
|
||||||
import org.imixs.workflow.exceptions.ModelException;
|
import org.imixs.workflow.exceptions.ModelException;
|
||||||
import org.imixs.workflow.exceptions.PluginException;
|
import org.imixs.workflow.exceptions.PluginException;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -16,6 +17,7 @@ import org.junit.jupiter.api.Test;
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
@Disabled
|
||||||
public class TestSEPATransform {
|
public class TestSEPATransform {
|
||||||
|
|
||||||
final static String ENCODING = "UTF-8";
|
final static String ENCODING = "UTF-8";
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import org.junit.jupiter.api.Test;
|
||||||
* A test to explore a corgosoft invoice event
|
* A test to explore a corgosoft invoice event
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
// @Disabled
|
@Disabled
|
||||||
public class TestCargosoftEvents {
|
public class TestCargosoftEvents {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(TestCargosoftEvents.class.getName());
|
private static Logger logger = Logger.getLogger(TestCargosoftEvents.class.getName());
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import org.imixs.workflow.ItemCollection;
|
||||||
import org.imixs.workflow.exceptions.PluginException;
|
import org.imixs.workflow.exceptions.PluginException;
|
||||||
import org.imixs.workflow.xml.XMLDataCollectionAdapter;
|
import org.imixs.workflow.xml.XMLDataCollectionAdapter;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import jakarta.xml.bind.JAXBException;
|
import jakarta.xml.bind.JAXBException;
|
||||||
|
|
@ -22,7 +23,7 @@ import jakarta.xml.bind.JAXBException;
|
||||||
* A simple example how to send an invoice document remote.
|
* A simple example how to send an invoice document remote.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
// @Disabled
|
@Disabled
|
||||||
public class TestSendInvoice {
|
public class TestSendInvoice {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(TestSendInvoice.class.getName());
|
private static Logger logger = Logger.getLogger(TestSendInvoice.class.getName());
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue