public PrepareResult prepare(HostValidator hostValidator, DeployLogger logger, PrepareParams params,
                                 Optional<ApplicationVersions> activeApplicationVersions, Instant now, File serverDbSessionDir,
                                 ApplicationPackage applicationPackage, SessionZooKeeperClient sessionZooKeeperClient) {
        ApplicationId applicationId = params.getApplicationId();
        Preparation preparation = new Preparation(hostValidator, logger, params, activeApplicationVersions,
                                                  TenantRepository.getTenantPath(applicationId.tenant()),
                                                  serverDbSessionDir, applicationPackage, sessionZooKeeperClient,
                                                  onnxModelCost, endpointCertificateSecretStores);
        preparation.preprocess();
        try {
            AllocatedHosts allocatedHosts = preparation.buildModels(now);
            preparation.makeResult(allocatedHosts);
            if ( ! params.isDryRun()) {
                FileReference fileReference = preparation.triggerDistributionOfApplicationPackage();
                preparation.writeStateZK(fileReference);
                preparation.writeEndpointCertificateMetadataZK();
                preparation.writeContainerEndpointsZK();
            }
            log.log(Level.FINE, () -> "time used " + params.getTimeoutBudget().timesUsed() + " : " + applicationId);
            return preparation.result();
        }
        catch (IllegalArgumentException e) {
            if (e instanceof InvalidApplicationException)
                throw e;
            throw new InvalidApplicationException("Invalid application package", e);
        }
    }
@Test
    public void require_that_endpoint_certificate_metadata_is_written() throws IOException {
        var applicationId = applicationId("test");
        var params = new PrepareParams.Builder().applicationId(applicationId).endpointCertificateMetadata("{\"keyName\": \"vespa.tlskeys.tenant1--app1-key\", \"certName\":\"vespa.tlskeys.tenant1--app1-cert\", \"version\": 7}").build();
        secretStore.put("vespa.tlskeys.tenant1--app1-cert", 7, X509CertificateUtils.toPem(certificate));
        secretStore.put("vespa.tlskeys.tenant1--app1-key", 7, KeyUtils.toPem(keyPair.getPrivate()));
        prepare(new File("src/test/resources/deploy/hosted-app"), params);

        // Read from zk and verify cert and key are available
        Path tenantPath = TenantRepository.getTenantPath(applicationId.tenant());
        Optional<EndpointCertificateSecrets> endpointCertificateSecrets = new EndpointCertificateMetadataStore(curator, tenantPath)
                .readEndpointCertificateMetadata(applicationId)
                .flatMap(p -> new EndpointCertificateRetriever(List.of(new DefaultEndpointCertificateSecretStore(secretStore))).readEndpointCertificateSecrets(p));

        assertTrue(endpointCertificateSecrets.isPresent());
        assertTrue(endpointCertificateSecrets.get().key().startsWith("-----BEGIN EC PRIVATE KEY"));
        assertTrue(endpointCertificateSecrets.get().certificate().startsWith("-----BEGIN CERTIFICATE"));
    }