From c8d071fda92562a8591d06ee023120a2dc0484f0 Mon Sep 17 00:00:00 2001 From: Andreas Kretschmer Date: Wed, 12 Jun 2024 16:15:30 +0200 Subject: [PATCH] Implement JSON/YAML message dumper --- pom.xml | 5 + .../pki/cmpracomponent/util/FileTracer.java | 116 +++-- .../util/JsonYamlMessageDumper.java | 430 ++++++++++++++++++ .../test/TestRrWithPolling.java | 8 + .../cmpracomponent/test/TestFileTracer.java | 104 +++++ 5 files changed, 628 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/siemens/pki/cmpracomponent/util/JsonYamlMessageDumper.java create mode 100644 src/test/java/com/siemens/pki/cmpracomponent/test/TestFileTracer.java diff --git a/pom.xml b/pom.xml index 5076a9f4..7fa8c9cb 100644 --- a/pom.xml +++ b/pom.xml @@ -242,6 +242,11 @@ jackson-databind 2.17.0 + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.17.0 + org.jacoco jacoco-maven-plugin diff --git a/src/main/java/com/siemens/pki/cmpracomponent/util/FileTracer.java b/src/main/java/com/siemens/pki/cmpracomponent/util/FileTracer.java index 68d593f3..83f018ed 100644 --- a/src/main/java/com/siemens/pki/cmpracomponent/util/FileTracer.java +++ b/src/main/java/com/siemens/pki/cmpracomponent/util/FileTracer.java @@ -59,23 +59,41 @@ public class FileTracer { private static boolean enableAsn1Dump; + private static boolean enableJsonDump; + + private static boolean enableYamlDump; + static { final String dumpDirName = System.getProperty("dumpdir"); - if (dumpDirName != null) { - msgDumpDirectory = new File(dumpDirName); - if (!msgDumpDirectory.isDirectory() || !msgDumpDirectory.canWrite()) { - LOGGER.error(msgDumpDirectory + " is not writable, disable dump"); - msgDumpDirectory = null; - } else { - LOGGER.info("dump transactions below " + msgDumpDirectory); - } - } - // "pem+txt+der+asn1" - final String dumpFormat = System.getProperty("dumpformat", "txt").toLowerCase(); + // "pem+txt+der+asn1+json+yaml" + final String dumpFormat = System.getProperty("dumpformat", "yaml").toLowerCase(); + init(dumpDirName, dumpFormat); + } + + /** + * + * @param dumpDirName directory to dump to + * @param dumpFormat dump format to use, one or more of + * "pem,txt,der,asn1,json,yaml" concatinated in one string + */ + public static void init(final String dumpDirName, final String dumpFormat) { enablePemDump = dumpFormat.contains("pem"); enableTxtDump = dumpFormat.contains("txt"); enableDerDump = dumpFormat.contains("der"); enableAsn1Dump = dumpFormat.contains("asn"); + enableJsonDump = dumpFormat.contains("json"); + enableYamlDump = dumpFormat.contains("yaml"); + + if (dumpDirName == null) { + return; + } + msgDumpDirectory = new File(dumpDirName); + if (!msgDumpDirectory.isDirectory() || !msgDumpDirectory.canWrite()) { + LOGGER.error(msgDumpDirectory + " is not writable, disable dump"); + msgDumpDirectory = null; + } else { + LOGGER.info("dump transactions below " + msgDumpDirectory); + } } private static final AtomicLong messagecounter = new AtomicLong(0); @@ -85,38 +103,34 @@ public class FileTracer { * * @param msg message to dump * @param interfaceName file name prefix to use + * @return directory where the log goes in */ - public static void logMessage(final PKIMessage msg, final String interfaceName) { - if (msgDumpDirectory == null - || msg == null - || !enablePemDump && !enableTxtDump && !enableDerDump && !enableAsn1Dump) { - return; + public static File logMessage(final PKIMessage msg, final String interfaceName) { + if (msgDumpDirectory == null || msg == null) { + return null; + } + if (!isPemOrDerOutEnabled() && !isTxtOutEnabled() && !enableJsonDump && !enableYamlDump) { + return null; } try { - final String tidAsString = defaultIfNull( - ifNotNull( - msg.getHeader().getTransactionID(), - tid -> B64_ENCODER_WITHOUT_PADDING.encodeToString(tid.getOctets())), - "null"); - final String subDirName = "trans_" + tidAsString; - final File subDir = new File(msgDumpDirectory, subDirName); - if (!subDir.isDirectory()) { - subDir.mkdirs(); - } + final File subDir = getCreateTransactionDirectory(msg); final String fileprefix = String.format( "%03d_%s_%s", messagecounter.incrementAndGet(), interfaceName, MessageDumper.msgTypeAsString(msg)); - final byte[] encodedMessage = enableDerDump || enablePemDump ? msg.getEncoded(ASN1Encoding.DER) : null; - if (enableDerDump) { - try (final FileOutputStream binOut = new FileOutputStream(new File(subDir, fileprefix + ".PKI"))) { - binOut.write(encodedMessage); + if (isPemOrDerOutEnabled()) { + final byte[] encodedMessage = msg.getEncoded(ASN1Encoding.DER); + if (enableDerDump) { + try (final FileOutputStream binOut = new FileOutputStream(new File(subDir, fileprefix + ".PKI"))) { + binOut.write(encodedMessage); + } } - } - if (enablePemDump) { - try (final PemWriter pemOut = new PemWriter(new FileWriter(new File(subDir, fileprefix + ".pem")))) { - pemOut.writeObject(new PemObject("PKIXCMP", encodedMessage)); + if (enablePemDump) { + try (final PemWriter pemOut = + new PemWriter(new FileWriter(new File(subDir, fileprefix + ".pem")))) { + pemOut.writeObject(new PemObject("PKIXCMP", encodedMessage)); + } } } - if (enableAsn1Dump || enableTxtDump) { + if (isTxtOutEnabled()) { try (final FileWriter txtOut = new FileWriter(new File(subDir, fileprefix + ".txt"))) { if (enableTxtDump) { txtOut.write(MessageDumper.dumpPkiMessage(msg)); @@ -126,11 +140,43 @@ public static void logMessage(final PKIMessage msg, final String interfaceName) } } } + if (enableJsonDump) { + try (final FileWriter txtOut = new FileWriter(new File(subDir, fileprefix + ".json"))) { + txtOut.write(JsonYamlMessageDumper.dumpPkiMessageAsJson(msg)); + } + } + if (enableYamlDump) { + try (final FileWriter txtOut = new FileWriter(new File(subDir, fileprefix + ".yaml"))) { + txtOut.write(JsonYamlMessageDumper.dumpPkiMessageAsYaml(msg)); + } + } + return subDir; } catch (final Exception e) { LOGGER.error("error writing dump", e); + return null; } } + private static File getCreateTransactionDirectory(final PKIMessage msg) { + final String transactionId = ifNotNull( + msg.getHeader().getTransactionID(), tid -> B64_ENCODER_WITHOUT_PADDING.encodeToString(tid.getOctets())); + final String tidAsString = defaultIfNull(transactionId, "null"); + final String subDirName = "trans_" + tidAsString; + final File subDir = new File(msgDumpDirectory, subDirName); + if (!subDir.isDirectory()) { + subDir.mkdirs(); + } + return subDir; + } + + private static boolean isTxtOutEnabled() { + return enableAsn1Dump || enableTxtDump; + } + + private static boolean isPemOrDerOutEnabled() { + return enableDerDump || enablePemDump; + } + // utility class private FileTracer() {} } diff --git a/src/main/java/com/siemens/pki/cmpracomponent/util/JsonYamlMessageDumper.java b/src/main/java/com/siemens/pki/cmpracomponent/util/JsonYamlMessageDumper.java new file mode 100644 index 00000000..547b5fd4 --- /dev/null +++ b/src/main/java/com/siemens/pki/cmpracomponent/util/JsonYamlMessageDumper.java @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2024 Siemens AG + * + * 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 + * + * http://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 + */ +package com.siemens.pki.cmpracomponent.util; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.Version; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.cfg.MapperBuilder; +import com.fasterxml.jackson.databind.introspect.AnnotatedMember; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.text.ParseException; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.bouncycastle.asn1.ASN1Enumerated; +import org.bouncycastle.asn1.ASN1GeneralizedTime; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.cmp.PKIBody; +import org.bouncycastle.asn1.cmp.PKIFreeText; +import org.bouncycastle.asn1.cmp.PKIMessage; +import org.bouncycastle.asn1.cmp.PKIStatusInfo; +import org.bouncycastle.asn1.cmp.PollRepContent; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.Extensions; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; + +/** + * A utility class providing functions for dumping messages in JSON/YAML format. + */ +public class JsonYamlMessageDumper { + + private static ObjectMapper jsonMapper; + + private static ObjectMapper yamlMapper; + + /** + * Serializer for {@link ByteArrayInputStream} + */ + public static class ByteArrayInputStreamSerializer extends JsonSerializer { + /** + */ + @Override + public Class handledType() { + return ByteArrayInputStream.class; + } + + @Override + public void serialize( + final ByteArrayInputStream value, final JsonGenerator jsonGenerator, final SerializerProvider provider) + throws IOException { + if (value == null) { + jsonGenerator.writeNull(); + return; + } + if ("encoded".equals(jsonGenerator.getOutputContext().getCurrentName())) { + jsonGenerator.writeNull(); + } else { + jsonGenerator.writeBinary(value.readAllBytes()); + } + } + } + + /** + * Serializer for {@link ByteArrayInputStream} + */ + public static class PKIBodySerializer extends JsonSerializer { + + @Override + public Class handledType() { + return PKIBody.class; + } + + @Override + public void serialize(final PKIBody value, final JsonGenerator jsonGenerator, final SerializerProvider provider) + throws IOException { + if (value == null) { + jsonGenerator.writeNull(); + return; + } + jsonGenerator.writeStartObject(); + jsonGenerator.writeStringField("type", MessageDumper.msgTypeAsString(value)); + jsonGenerator.writeStringField( + "ContentClass", value.getContent().getClass().getSimpleName()); + jsonGenerator.writePOJOField("content", value.getContent()); + jsonGenerator.writeEndObject(); + } + } + + /** + * Serializer for {@link PollRepContent} + */ + public static class PollRepContentSeralizer extends JsonSerializer { + + @Override + public Class handledType() { + return PollRepContent.class; + } + + class PollRepContentWrapper { + public PollRepContentWrapper(PollRepContent wrapped) { + this.wrapped = wrapped; + } + + private final PollRepContent wrapped; + + public Entry[] getEntries() { + int size = wrapped.size(); + Entry[] ret = new Entry[size]; + for (int i = 0; i < size; i++) { + ret[i] = new Entry(i); + } + return ret; + } + + class Entry { + private final int index; + + public Entry(int index) { + super(); + this.index = index; + } + + public ASN1Integer getCertReqId() { + return wrapped.getCertReqId(index); + } + + public ASN1Integer getCheckAfter() { + return wrapped.getCheckAfter(index); + } + + public PKIFreeText getReason() { + return wrapped.getReason(index); + } + } + } + + @Override + public void serialize( + final PollRepContent value, final JsonGenerator jsonGenerator, final SerializerProvider provider) + throws IOException { + if (value == null) { + jsonGenerator.writeNull(); + return; + } + jsonGenerator.writePOJO(new PollRepContentWrapper(value).getEntries()); + } + } + + /** + * Serializer for {@link Extensions} + */ + public static class ExtensionsSeralizer extends JsonSerializer { + + @Override + public Class handledType() { + return Extensions.class; + } + + class ExtensionsWrapper { + public ExtensionsWrapper(Extensions wrapped) { + this.wrapped = wrapped; + } + + private final Extensions wrapped; + + public List getEntries() { + return Arrays.stream(wrapped.getExtensionOIDs()) + .map(wrapped::getExtension) + .collect(Collectors.toList()); + } + } + + @Override + public void serialize( + final Extensions value, final JsonGenerator jsonGenerator, final SerializerProvider provider) + throws IOException { + if (value == null) { + jsonGenerator.writeNull(); + return; + } + jsonGenerator.writePOJO(new ExtensionsWrapper(value).getEntries()); + } + } + + public static class ArraySerializer extends JsonSerializer { + + private final Class handledType; + + private final BiFunction getArray; + + private Function sizeSupplier; + + public ArraySerializer(Class handledType, Function size, BiFunction getArray) { + this.handledType = handledType; + this.getArray = getArray; + this.sizeSupplier = size; + } + + @Override + public Class handledType() { + return handledType; + } + + @Override + public void serialize(final T value, final JsonGenerator jsonGenerator, final SerializerProvider provider) + throws IOException { + + int size = sizeSupplier.apply(value); + if (size < 1 || value == null) { + jsonGenerator.writeNull(); + return; + } + jsonGenerator.writeStartArray(); + for (int i = 0; i < size; i++) { + jsonGenerator.writeObject(getArray.apply(i, value)); + } + jsonGenerator.writeEndArray(); + } + } + + /** + * generic toString Serializer + */ + public static class GenericSerializer extends JsonSerializer { + + private final Class handledType; + + private final Function mapToString; + + public GenericSerializer(Class handledType) { + this.handledType = handledType; + mapToString = T::toString; + } + + public GenericSerializer(Class handledType, Function mapToString) { + super(); + this.handledType = handledType; + this.mapToString = mapToString; + } + + @Override + public Class handledType() { + return handledType; + } + + @Override + public void serialize(final T value, final JsonGenerator jsonGenerator, final SerializerProvider provider) + throws IOException { + if (value == null) { + jsonGenerator.writeNull(); + return; + } + jsonGenerator.writeString(mapToString.apply(value)); + } + } + + /** + * Serializer for {@link SubjectPublicKeyInfoSerializer} + */ + public static class SubjectPublicKeyInfoSerializer extends JsonSerializer { + + @Override + public Class handledType() { + return SubjectPublicKeyInfo.class; + } + + @Override + public void serialize( + final SubjectPublicKeyInfo value, final JsonGenerator jsonGenerator, final SerializerProvider provider) + throws IOException { + if (value == null) { + jsonGenerator.writeNull(); + return; + } + jsonGenerator.writeStartObject(); + jsonGenerator.writeStringField( + "Algorithm", + MessageDumper.getOidDescriptionForOid(value.getAlgorithm().getAlgorithm()) + .toString()); + try { + ASN1Primitive parsedKey = value.parsePublicKey(); + jsonGenerator.writePOJOField("ParsedKey", parsedKey); + } catch (IOException ex) { + jsonGenerator.writePOJOField("UnparsedKeyData", value.getPublicKeyData()); + } + jsonGenerator.writeEndObject(); + } + } + + /** + * Dump PKI message in JSON format. + * + * @param msg PKI message to be dumped + * @return JSON representation of the PKI message + */ + public static final String dumpPkiMessageAsJson(final PKIMessage msg) { + if (msg == null) { + return ""; + } + try { + return getJsonMapper().writeValueAsString(msg); + } catch (JsonProcessingException e) { + return e.getLocalizedMessage(); + } + } + + /** + * Dump PKI message in YAML format. + * + * @param msg PKI message to be dumped + * @return YAML representation of the PKI message + */ + public static final String dumpPkiMessageAsYaml(final PKIMessage msg) { + if (msg == null) { + return ""; + } + try { + return getYamlMapper().writeValueAsString(msg); + } catch (JsonProcessingException e) { + return e.getLocalizedMessage(); + } + } + + private static ObjectMapper initMapper(MapperBuilder builder) { + ObjectMapper mapper = builder.enable(MapperFeature.AUTO_DETECT_IS_GETTERS) + .enable(SerializationFeature.INDENT_OUTPUT) + .configure(SerializationFeature.WRITE_SELF_REFERENCES_AS_NULL, true) + .configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, false) + .configure(SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS, true) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + .serializationInclusion(Include.NON_NULL) + .annotationIntrospector(new JacksonAnnotationIntrospector() { + private static final long serialVersionUID = 1L; + + @Override + public boolean hasIgnoreMarker(AnnotatedMember m) { + return m.getDeclaringClass() == ASN1Object.class || super.hasIgnoreMarker(m); + } + + @Override + public String findImplicitPropertyName(AnnotatedMember m) { + String methodName = m.getName(); + if (methodName != null && methodName.startsWith("to") && methodName.endsWith("Array")) { + return methodName.substring(2, methodName.length() - 5); + } + return super.findImplicitPropertyName(m); + } + }) + .build(); + final SimpleModule simpleModule = new SimpleModule("Dump", new Version(1, 0, 0, null, null, null)); + simpleModule.addSerializer(new ByteArrayInputStreamSerializer()); + simpleModule.addSerializer(new PKIBodySerializer()); + simpleModule.addSerializer(new SubjectPublicKeyInfoSerializer()); + simpleModule.addSerializer(new GenericSerializer<>(ASN1Primitive.class)); + simpleModule.addSerializer(new GenericSerializer<>(GeneralName.class)); + simpleModule.addSerializer(new GenericSerializer<>(Number.class)); + simpleModule.addSerializer(new GenericSerializer<>(CharSequence.class)); + simpleModule.addSerializer(new GenericSerializer<>(X500Name.class)); + simpleModule.addSerializer(new GenericSerializer<>(Date.class)); + simpleModule.addSerializer(new GenericSerializer<>(PKIStatusInfo.class, MessageDumper::pkiStatus2String)); + simpleModule.addSerializer(new GenericSerializer<>(ASN1GeneralizedTime.class, a -> { + try { + return a.getDate().toString(); + } catch (ParseException e) { + return e.getLocalizedMessage(); + } + })); + simpleModule.addSerializer( + new GenericSerializer<>(ASN1ObjectIdentifier.class, a -> MessageDumper.getOidDescriptionForOid(a) + .toString())); + simpleModule.addSerializer( + new GenericSerializer<>(ASN1Enumerated.class, a -> a.getValue().toString())); + simpleModule.addSerializer(new ArraySerializer<>( + PKIFreeText.class, p -> p.size(), (i, p) -> p.getStringAtUTF8(i).toString())); + simpleModule.addSerializer(new PollRepContentSeralizer()); + simpleModule.addSerializer(new ExtensionsSeralizer()); + mapper.registerModule(simpleModule); + return mapper; + } + + private static ObjectMapper getJsonMapper() { + if (jsonMapper == null) { + jsonMapper = initMapper(JsonMapper.builder()); + } + return jsonMapper; + } + + private static ObjectMapper getYamlMapper() { + if (yamlMapper == null) { + yamlMapper = initMapper(YAMLMapper.builder()); + } + return yamlMapper; + } + + private JsonYamlMessageDumper() {} +} diff --git a/src/test/java/com/siemens/pki/cmpclientcomponent/test/TestRrWithPolling.java b/src/test/java/com/siemens/pki/cmpclientcomponent/test/TestRrWithPolling.java index ecd3ab19..8cd64177 100644 --- a/src/test/java/com/siemens/pki/cmpclientcomponent/test/TestRrWithPolling.java +++ b/src/test/java/com/siemens/pki/cmpclientcomponent/test/TestRrWithPolling.java @@ -32,7 +32,9 @@ import com.siemens.pki.cmpracomponent.configuration.VerificationContext; import com.siemens.pki.cmpracomponent.test.framework.ConfigurationFactory; import com.siemens.pki.cmpracomponent.test.framework.SignatureValidationCredentials; +import com.siemens.pki.cmpracomponent.util.FileTracer; import java.math.BigInteger; +import java.nio.file.Files; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.ArrayList; @@ -49,6 +51,12 @@ public void setUp() throws Exception { launchDelayedCmpCaAndRa(ConfigurationFactory.buildSignatureBasedDownstreamConfiguration()); } + @Test + public void testRrWithPollingAndDump() throws Exception { + FileTracer.init(Files.createTempDirectory("dump").toFile().getAbsolutePath(), "pem,txt,der,asn1,json,yaml"); + testRrWithPolling(); + } + /** * Revoking a certificate/Handling Delayed Delivery * diff --git a/src/test/java/com/siemens/pki/cmpracomponent/test/TestFileTracer.java b/src/test/java/com/siemens/pki/cmpracomponent/test/TestFileTracer.java new file mode 100644 index 00000000..172070ab --- /dev/null +++ b/src/test/java/com/siemens/pki/cmpracomponent/test/TestFileTracer.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2024 Siemens AG + * + * 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 + * + * http://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 + */ +package com.siemens.pki.cmpracomponent.test; + +import static org.junit.Assert.assertTrue; + +import com.siemens.pki.cmpracomponent.msggeneration.PkiMessageGenerator; +import com.siemens.pki.cmpracomponent.test.framework.HeaderProviderForTest; +import com.siemens.pki.cmpracomponent.util.FileTracer; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; +import org.bouncycastle.asn1.cmp.PKIMessage; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * test the {@link FileTracer} + */ +@RunWith(Parameterized.class) +public class TestFileTracer { + + @Parameters(name = "{index}: dumpDirName=>{0}, dumpFormat=>{1}") + public static List data() throws IOException { + String tempDir = Files.createTempDirectory("dumptest").toFile().getAbsolutePath(); + Object[][] ret = new Object[][] { + {null, "asn", (Function) (f) -> f == null}, + {tempDir, "", (Function) (f) -> f == null}, + {tempDir, "pem,txt,der,asn1,json,yaml", (Function) (f) -> f.listFiles().length == 5}, + { + tempDir, + "pem", + (Function) + (f) -> f.listFiles()[0].getAbsolutePath().endsWith(".pem") + }, + { + tempDir, + "txt", + (Function) + (f) -> f.listFiles()[0].getAbsolutePath().endsWith(".txt") + }, + { + tempDir, + "der", + (Function) + (f) -> f.listFiles()[0].getAbsolutePath().endsWith(".PKI") + }, + { + tempDir, + "asn1", + (Function) + (f) -> f.listFiles()[0].getAbsolutePath().endsWith(".txt") + }, + { + tempDir, + "json", + (Function) + (f) -> f.listFiles()[0].getAbsolutePath().endsWith(".json") + }, + { + tempDir, + "yaml", + (Function) + (f) -> f.listFiles()[0].getAbsolutePath().endsWith(".yaml") + }, + {"unwritable", "pem,txt,der,asn1,json,yaml", (Function) (f) -> f == null}, + }; + return Arrays.asList(ret); + } + + private Function testValidator; + + public TestFileTracer(String dumpDirName, String dumpFormat, Function testValidator) { + FileTracer.init(dumpDirName, dumpFormat); + this.testValidator = testValidator; + } + + @Test + public void testDumper() throws Exception { + PKIMessage testMessage = PkiMessageGenerator.generateUnprotectMessage( + new HeaderProviderForTest("noProfile"), PkiMessageGenerator.generatePkiConfirmBody()); + assertTrue(testValidator.apply(FileTracer.logMessage(testMessage, "testdumper"))); + } +}