class KennaSecurityUploader extends AbstractIntegrationPoint implements PortfolioFindingUploader {

    private static final Logger LOGGER = Logger.getLogger(KennaSecurityUploader.class);
    private static final String ASSET_EXTID_PROPERTY = "kenna.asset.external_id";
    private static final String API_ROOT = "https://api.kennasecurity.com";
    private static final String CONNECTOR_UPLOAD_URL = API_ROOT + "/connectors/%s/data_file";

    private String connectorId;

    @Override
    public String name() {
        return "Kenna Security";
    }

    @Override
    public String description() {
        return "Pushes Dependency-Track findings to Kenna Security";
    }

    @Override
    public boolean isEnabled() {
        final ConfigProperty enabled = qm.getConfigProperty(KENNA_ENABLED.getGroupName(), KENNA_ENABLED.getPropertyName());
        final ConfigProperty connector = qm.getConfigProperty(KENNA_CONNECTOR_ID.getGroupName(), KENNA_CONNECTOR_ID.getPropertyName());
        if (enabled != null && Boolean.valueOf(enabled.getPropertyValue()) && connector != null && connector.getPropertyValue() != null) {
            connectorId = connector.getPropertyValue();
            return true;
        }
        return false;
    }

    @Override
    public InputStream process() {<FILL_FUNCTION_BODY>}

    @Override
    public void upload(final InputStream payload) {
        LOGGER.debug("Uploading payload to KennaSecurity");
        final ConfigProperty tokenProperty = qm.getConfigProperty(KENNA_TOKEN.getGroupName(), KENNA_TOKEN.getPropertyName());
        try {
            final String token = DataEncryption.decryptAsString(tokenProperty.getPropertyValue());
            HttpPost request = new HttpPost(String.format(CONNECTOR_UPLOAD_URL, connectorId));
            request.addHeader("X-Risk-Token", token);
            request.addHeader("accept", "application/json");
            List<NameValuePair> nameValuePairList = new ArrayList<>();
            nameValuePairList.add(new BasicNameValuePair("run", "true"));
            request.setEntity(new UrlEncodedFormEntity(nameValuePairList, StandardCharsets.UTF_8));
            HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                    .addBinaryBody("file", payload, ContentType.APPLICATION_JSON, "findings.json")
                    .build();
            request.setEntity(data);
            try (CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) {
                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK && response.getEntity() != null) {
                    String responseString = EntityUtils.toString(response.getEntity());
                    final JSONObject root = new JSONObject(responseString);
                    if (root.getString("success").equals("true")) {
                        LOGGER.debug("Successfully uploaded KDI");
                        return;
                    }
                    LOGGER.warn("An unexpected response was received uploading findings to Kenna Security");
                } else {
                    handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase());
                }
            }
        } catch (Exception e) {
            LOGGER.error("An error occurred attempting to upload findings to Kenna Security", e);
        }
    }
}

        LOGGER.debug("Processing...");
        final KennaDataTransformer kdi = new KennaDataTransformer(qm);
        for (final Project project : qm.getAllProjects()) {
            final ProjectProperty externalId = qm.getProjectProperty(project, KENNA_ENABLED.getGroupName(), ASSET_EXTID_PROPERTY);
            if (externalId != null && externalId.getPropertyValue() != null) {
                LOGGER.debug("Transforming findings for project: " + project.getUuid() + " to KDI format");
                kdi.process(project, externalId.getPropertyValue());
            }
        }
        return new ByteArrayInputStream(kdi.generate().toString().getBytes());
    
<methods>public non-sealed void <init>() ,public void handleException(Logger, java.lang.Exception) ,public void handleUnexpectedHttpResponse(Logger, java.lang.String, int, java.lang.String) ,public void setQueryManager(org.dependencytrack.persistence.QueryManager) <variables>protected org.dependencytrack.persistence.QueryManager qm