Files
qbit-printing/dev/java/S3PrintingQualification.java
T
james.maesandCodex 1a0964ef23 chore: enforce owned source copyright notices (#25)
* chore(standards): preserve owned-source copyright notices

Add accurate repository copyright and license comments to 50 owned source/build/configuration files. Preserve existing holders, upstream wrappers, legal payloads and schema/data exemptions. Exact inverse-byte reconstruction and applicable parser/token/AST checks prove comment-only changes; existing relevant regressions pass.

Co-Authored-By: Codex (GPT-6) <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>

* chore: enforce owned source copyright notices

Check real leading comments against explicit repository provenance and retain existing native style gates.

Co-Authored-By: Codex GPT-6 <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>

---------

Signed-off-by: James Maes <james@kof22.com>
Co-authored-by: Codex (GPT-6) <noreply@openai.com>
2026-11-01 12:41:00 -06:00

221 lines
16 KiB
Java

/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2026. Kingsrook, LLC
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
* contact@kingsrook.com
* https://github.com/Kingsrook/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0
import com.kingsrook.qbits.printing.*;
import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.model.metadata.*;
import com.kingsrook.qqq.backend.core.model.metadata.authentication.QAuthenticationMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.fields.*;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.module.filesystem.s3.model.metadata.*;
import com.kingsrook.qqq.backend.module.filesystem.base.model.metadata.Cardinality;
import com.kingsrook.qqq.backend.module.filesystem.s3.utils.S3ClientFactory;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.security.MessageDigest;
import java.sql.*;
import java.time.Instant;
import java.util.*;
import org.json.*;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;
/** Non-listening synthetic harness. Never routes work to a Windows device. */
public final class S3PrintingQualification {
private static final String TABLE = "printing_documents";
private static final JSONArray CHECKS = new JSONArray();
private static final JSONArray DOCUMENTS = new JSONArray();
private static final Map<String, String> OBJECT_KEYS = new HashMap<>();
private static DriverDataSource database;
private static S3Client s3;
private static String bucket;
private static String otherBucket;
public static void main(String[] args) throws Exception {
Path output = Path.of(args[0]).toAbsolutePath();
Files.createDirectories(output);
String run = args[2];
bucket = "printing-fixture-" + run;
otherBucket = "printing-canary-" + run;
S3BackendMetaData backend = new S3BackendMetaData().withName("printing_s3_" + run)
.withBucketName(bucket).withEndpoint(args[1]).withPathStyleAccess(true).withRegion("us-east-1")
.withAccessKey(System.getenv("MINIO_ROOT_USER")).withSecretKey(System.getenv("MINIO_ROOT_PASSWORD"));
backend.setConnectTimeoutMillis(3000);
backend.setSocketTimeoutMillis(15000);
QInstance instance = new QInstance();
// Required metadata only: this harness opens no HTTP endpoint or user session.
instance.withInstanceDefaultAuthentication(new QAuthenticationMetaData().withName("fixture").withType(QAuthenticationType.MOCK));
instance.addBackend(backend);
instance.addTable(new QTableMetaData().withName(TABLE).withBackendName(backend.getName())
.withBackendDetails(new S3TableBackendDetails().withCardinality(Cardinality.ONE)
.withFileNameFieldName("id").withContentsFieldName("content")).withPrimaryKeyField("id")
.withField(new QFieldMetaData("id", QFieldType.STRING)).withField(new QFieldMetaData("content", QFieldType.BLOB)));
database = new DriverDataSource("jdbc:h2:file:" + output.resolve("synthetic-data").toString().replace('\\', '/'), "sa", "");
try {
s3 = S3ClientFactory.getClient(backend);
s3.createBucket(CreateBucketRequest.builder().bucket(bucket).build());
s3.createBucket(CreateBucketRequest.builder().bucket(otherBucket).build());
s3.putObject(PutObjectRequest.builder().bucket(bucket).key("unrelated/canary.txt").build(), RequestBody.fromString("synthetic unrelated object"));
s3.putObject(PutObjectRequest.builder().bucket(otherBucket).key("canary.txt").build(), RequestBody.fromString("synthetic separate bucket"));
PrintingService a = service(instance, "fixture-tenant-a");
PrintingService b = service(instance, "fixture-tenant-b");
String deviceA = enroll(a);
String deviceB = enroll(b);
byte[] pdf = PrintingTestDocuments.pdf();
byte[] zpl = "^XA^FO20,20^ADN,30,18^FDSYNTHETIC STORAGE TEST ONLY^FS^XZ".getBytes(StandardCharsets.US_ASCII);
byte[] large = new byte[6 * 1024 * 1024 + 71];
Arrays.fill(large, (byte)'A');
System.arraycopy("^XA^FX".getBytes(StandardCharsets.US_ASCII), 0, large, 0, 6);
System.arraycopy("^FS^XZ".getBytes(StandardCharsets.US_ASCII), 0, large, large.length - 6, 6);
String pdfJob = submitCheck(a, deviceA, "small-pdf", "PDF", pdf, false);
finish(a, deviceA, pdfJob, "SPOOLED");
String zplJob = submitCheck(a, deviceA, "small-zpl", "ZPL", zpl, false);
finish(a, deviceA, zplJob, "SPOOLED");
String largeJob = submitCheck(a, deviceA, "multipart-zpl", "ZPL", large, true);
finish(a, deviceA, largeJob, "SPOOLED");
String foreignJob = submitCheck(b, deviceB, "foreign-zpl", "ZPL", zpl, false);
finish(b, deviceB, foreignJob, "SPOOLED");
String foreignRef = reference(foreignJob);
String ownRef = reference(pdfJob);
check(!ownRef.split("/")[1].equals(foreignRef.split("/")[1]), "tenant prefixes differ");
expectStatus(404, () -> a.content(deviceA, foreignJob), "foreign tenant job download denied");
expectStatus(404, () -> a.content(deviceB, foreignJob), "foreign tenant device rejected");
execute("UPDATE printing_job SET content_reference=? WHERE id=?", foreignRef, pdfJob);
expectStatus(409, () -> a.content(deviceA, pdfJob), "foreign stored reference rejected");
execute("UPDATE printing_job SET content_reference=? WHERE id=?", ownRef, pdfJob);
check(Arrays.equals(zpl, b.content(deviceB, foreignJob)), "foreign object unchanged after rejection");
String failed = submitCheck(a, deviceA, "protected-failed", "ZPL", zpl, false);
finish(a, deviceA, failed, "FAILED");
String unknown = submitCheck(a, deviceA, "protected-unknown", "ZPL", zpl, false);
finish(a, deviceA, unknown, "OUTCOME_UNKNOWN");
String active = a.submit(request(deviceA, "protected-queued", "ZPL", zpl)).getString("jobId");
String old = Instant.now().minusSeconds(400L * 86400).toString();
for(String id : List.of(pdfJob, largeJob, foreignJob, failed, unknown, active)) {
execute("UPDATE printing_job SET created_at=?,completed_at=? WHERE id=?", old, old, id);
}
int before = objectCount();
check(a.runRetention() == 2, "tenant A retention removes exactly two aged successful documents");
check(objectCount() == before - 2, "object count reflects exact two removals");
missing(OBJECT_KEYS.get(ownRef));
missing(OBJECT_KEYS.get(reference(largeJob)));
expectStatus(410, () -> a.content(deviceA, pdfJob), "expired document returns 410");
check(a.submit(request(deviceA, "small-pdf", "PDF", pdf)).getString("jobId").equals(pdfJob), "idempotent replay survives retention without reupload");
check(objectCount() == before - 2, "post-retention replay creates no object");
for(String id : List.of(zplJob, foreignJob, failed, unknown, active)) {
check(s3.headObject(HeadObjectRequest.builder().bucket(bucket).key(objectKey(reference(id))).build()).contentLength() == zpl.length,
"protected object retained: " + status(id));
}
check(s3.getObjectAsBytes(GetObjectRequest.builder().bucket(bucket).key("unrelated/canary.txt").build()).asUtf8String().equals("synthetic unrelated object"), "unrelated same-bucket canary preserved");
check(s3.getObjectAsBytes(GetObjectRequest.builder().bucket(otherBucket).key("canary.txt").build()).asUtf8String().equals("synthetic separate bucket"), "separate bucket canary preserved");
check(a.runRetention() == 0, "repeated cleanup is idempotent");
check(b.runRetention() == 1, "tenant B cleanup independently removes its one eligible document");
check(s3.listMultipartUploads(ListMultipartUploadsRequest.builder().bucket(bucket).build()).uploads().isEmpty(), "no incomplete multipart uploads remain");
check(QContext.getQSession() == null, "storage restores original absent QQQ session");
JSONObject result = new JSONObject().put("passed", true).put("timestamp", Instant.now().toString())
.put("checks", CHECKS).put("documents", DOCUMENTS).put("runtimeJarCount", 204)
.put("appRevision", System.getenv("PRINTING_SOURCE_COMMIT"))
.put("h2Version", org.h2.engine.Constants.VERSION).put("retentionDays", a.getRetentionSettings().getInt("days"))
.put("transport", "loopback HTTP S3-compatible only").put("hardwarePrinting", false)
.put("qualifies", "QQQ StorageAction / AWS SDK v2 S3 data-plane behavior against disposable MinIO")
.put("doesNotQualify", new JSONArray(List.of("AWS IAM", "remote TLS", "production bucket ownership", "Object Lock/version lifecycle", "remote deployment", "hardware printing")));
Files.writeString(output.resolve("results.json"), result.toString(2) + "\n");
System.out.println("PASS " + CHECKS.length() + " checks; " + DOCUMENTS.length() + " synthetic document round trips");
} finally {
Files.writeString(output.resolve("completed-checks.json"), new JSONObject().put("checks", CHECKS).put("documents", DOCUMENTS).toString(2) + "\n");
S3ClientFactory.clearCache();
QContext.clear();
}
}
private static PrintingService service(QInstance instance, String tenant) throws Exception {
PrintingService service = new PrintingService(database, tenant);
service.initialize(); service.configureStorage(instance, TABLE); return service;
}
private static String enroll(PrintingService service) throws Exception {
String id = service.enroll(service.createEnrollment("fixture", "Synthetic station")
.put("deviceName", "Synthetic station").put("agentVersion", "isolated-storage-fixture")).getString("deviceId");
service.inventory(id, new JSONArray().put(new JSONObject().put("printerId", "synthetic-never-dispatched")
.put("name", "Synthetic storage-only destination").put("status", "READY").put("formats", new JSONArray(List.of("PDF", "ZPL")))));
service.enablePrinter(id, "synthetic-never-dispatched", true); return id;
}
private static JSONObject request(String device, String key, String format, byte[] bytes) {
return new JSONObject().put("deviceId", device).put("printerId", "synthetic-never-dispatched").put("title", "Synthetic storage qualification")
.put("format", format).put("contentBase64", Base64.getEncoder().encodeToString(bytes)).put("idempotencyKey", key);
}
private static String submitCheck(PrintingService service, String device, String key, String format, byte[] bytes, boolean multipart) throws Exception {
JSONObject request = request(device, key, format, bytes);
String id = service.submit(request).getString("jobId");
int count = objectCount();
check(id.equals(service.submit(request).getString("jobId")) && count == objectCount(), key + " stable replay creates no object");
check(service.claim(device).getJSONObject("job").getString("jobId").equals(id), key + " claimed through production service");
byte[] actual = service.content(device, id);
check(Arrays.equals(bytes, actual) && sha(bytes).equals(sha(actual)), key + " download bytes and SHA256 match");
String ref = reference(id);
String actualKey = objectKey(ref);
HeadObjectResponse head = s3.headObject(HeadObjectRequest.builder().bucket(bucket).key(actualKey).build());
check(head.contentLength() == bytes.length, key + " object length exact");
check(head.contentType().equals(format.equals("PDF") ? "application/pdf" : "application/vnd.zebra-zpl"), key + " content type correct");
check(head.eTag().contains("-2") == multipart, key + " expected single/multipart object ETag");
try(var c = database.getConnection(); var statement = c.prepareStatement("SELECT content_base64,content_storage_table FROM printing_job WHERE id=?")) {
statement.setString(1, id); try(var rows = statement.executeQuery()) { check(rows.next() && rows.getString(1) == null && TABLE.equals(rows.getString(2)), key + " payload external, no inline database copy"); }
}
DOCUMENTS.put(new JSONObject().put("case", key).put("format", format).put("bytes", bytes.length).put("sha256", sha(bytes)).put("multipart", multipart).put("etag", head.eTag())
.put("objectKeyEqualsStoredReference", actualKey.equals(ref)).put("objectKeyPrefixBeforeReference", actualKey.substring(0, actualKey.length() - ref.length())));
return id;
}
private static void finish(PrintingService service, String device, String id, String status) throws Exception {
for(String phase : List.of("RECEIVED", "SUBMITTING", status)) service.event(device, id, new JSONObject().put("eventId", UUID.randomUUID().toString()).put("status", phase).put("message", "Synthetic receipt; no physical device or spooler used"));
}
private static String sha(byte[] bytes) throws Exception { return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(bytes)); }
private static int objectCount() { return s3.listObjectsV2(ListObjectsV2Request.builder().bucket(bucket).build()).contents().size(); }
private static String objectKey(String reference) {
String known = OBJECT_KEYS.get(reference);
if(known != null) return known;
List<String> matches = s3.listObjectsV2(ListObjectsV2Request.builder().bucket(bucket).build()).contents().stream()
.map(S3Object::key).filter(key -> key.endsWith(reference)).toList();
if(matches.size() != 1) throw new AssertionError("Expected exactly one synthetic object for stored reference");
String key = matches.getFirst();
String prefix = key.substring(0, key.length() - reference.length());
if(!prefix.isEmpty() && !prefix.matches("\\\\+")) throw new AssertionError("Unexpected physical S3 key prefix");
OBJECT_KEYS.put(reference, key);
return key;
}
private static String reference(String id) throws Exception { return field(id, "content_reference"); }
private static String status(String id) throws Exception { return field(id, "status"); }
private static String field(String id, String field) throws Exception {
try(var c = database.getConnection(); var statement = c.prepareStatement("SELECT " + field + " FROM printing_job WHERE id=?")) {
statement.setString(1,id); try(var rows=statement.executeQuery()) { if(!rows.next()) throw new AssertionError("Missing synthetic job"); return rows.getString(1); }
}
}
private static void execute(String sql, String... args) throws Exception {
try(var c = database.getConnection(); var statement = c.prepareStatement(sql)) { for(int i=0; i<args.length; i++) statement.setString(i+1,args[i]); statement.executeUpdate(); }
}
private static void check(boolean pass, String label) { if(!pass) throw new AssertionError(label); CHECKS.put(label); }
private static void missing(String ref) {
try { s3.headObject(HeadObjectRequest.builder().bucket(bucket).key(ref).build()); throw new AssertionError("Expected removed object"); }
catch(S3Exception exception) { check(exception.statusCode()==404,"eligible object absent from S3 after cleanup"); }
}
@FunctionalInterface private interface Checked { void run() throws Exception; }
private static void expectStatus(int status, Checked operation, String label) throws Exception {
try { operation.run(); throw new AssertionError(label); } catch(PrintingException exception) { check(exception.getStatus()==status,label); }
}
}