How to get REST API work on Java back-end?

Hello,

Now facing issue to get REST API to work on Java back-end. Source Code below goes to ClientProtocolException with message: “Transcription API call failed.”.

And yes I am made Personal Access Token for username admin and configured Wildcard SSL with Let’s Encrypt and made configuration to /conf/server.xml like below:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS"
           keystoreFile="conf/i4ware_keystore.jks"
           keystorePass="mypassword">
    <SSLHostConfig>
        <Certificate certificateKeystoreFile="conf/i4ware_keystore.jks"
                     certificateKeystorePassword="mypassword"
                     type="RSA" />
    </SSLHostConfig>
</Connector>
private String transcribeSpeech(String pageId, String attachmentFileName) throws IOException {
        Settings settings = globalSettingsManager.getGlobalSettings();
        String baseUrl = settings.getBaseUrl();

        // Ensure baseUrl is using HTTPS
        if (!baseUrl.startsWith("https")) {
            throw new IllegalArgumentException("Base URL must use HTTPS: " + baseUrl);
        }

        // Get attachments from Confluence page
        String attachmentsUrl = baseUrl + "/rest/api/content/" + pageId + "/child/attachment";
        HttpGet getAttachments = new HttpGet(attachmentsUrl);
        getAttachments.setHeader("Authorization", "Bearer " + confluenceApiKey);

        InputStream attachmentStream = null;
        try (CloseableHttpResponse response = httpClient.execute(getAttachments)) {
            int statusCode = response.getStatusLine().getStatusCode();
            String responseBody = EntityUtils.toString(response.getEntity());
            logger.debug("Attachments Response Status Code: " + statusCode);
            logger.debug("Attachments Response Body: " + responseBody);

            if (statusCode != HttpServletResponse.SC_OK) {
                throw new IOException("Failed to get attachments: " + responseBody);
            }

            // Parse the JSON response to find the desired attachment
            JSONObject jsonResponse = new JSONObject(responseBody);
            JSONArray attachments = jsonResponse.getJSONArray("results");

            String downloadLink = null;
            logger.debug("Looking for attachment with filename: " + attachmentFileName);
            for (int i = 0; i < attachments.length(); i++) {
                JSONObject attachment = attachments.getJSONObject(i);
                String title = attachment.getString("title");
                logger.debug("Found attachment: " + title);
                if (title.equals(attachmentFileName)) {
                    downloadLink = attachment.getJSONObject("_links").getString("download");
                    break;
                }
            }

            if (downloadLink == null) {
                throw new IOException("Attachment not found: " + attachmentFileName);
            }

            // Construct the full download URL
            String attachmentUrl = baseUrl + downloadLink;
            logger.debug("Attachment download URL: " + attachmentUrl);
            HttpGet getAttachment = new HttpGet(attachmentUrl);
            getAttachment.setHeader("Authorization", "Bearer " + confluenceApiKey);

            try (CloseableHttpResponse attachmentResponse = httpClient.execute(getAttachment)) {
                statusCode = attachmentResponse.getStatusLine().getStatusCode();
                if (statusCode != HttpServletResponse.SC_OK) {
                    String responseBodyAttachment = EntityUtils.toString(attachmentResponse.getEntity());
                    logger.error("Attachment Download Response Status Code: " + statusCode);
                    logger.error("Attachment Download Response Body: " + responseBodyAttachment);
                    throw new IOException("Failed to download attachment: " + responseBodyAttachment);
                }

                HttpEntity entity = attachmentResponse.getEntity();
                attachmentStream = entity.getContent();
            }
        } catch (ClientProtocolException e) {
            logger.error("ClientProtocolException while retrieving attachment from URL: " + attachmentsUrl, e);
            throw new IOException("ClientProtocolException: Failed to retrieve attachment from Confluence.", e);
        } catch (IOException e) {
            logger.error("IOException while retrieving attachment from URL: " + attachmentsUrl, e);
            throw new IOException("Failed to retrieve attachment from Confluence. Please check the pageId and attachmentFileName.", e);
        }

        // Transcribe the audio data
        HttpPost post = new HttpPost("https://api.openai.com/v1/audio/transcriptions");
        post.setHeader("Authorization", "Bearer " + apiKey);

        HttpEntity entity = MultipartEntityBuilder.create()
            .addBinaryBody("file", attachmentStream, ContentType.create("audio/ogg"), attachmentFileName)
            .addTextBody("model", "whisper-1", ContentType.create("text/plain", StandardCharsets.UTF_8))
            .build();

        post.setEntity(entity);

        String transcription;
        try (CloseableHttpResponse response = httpClient.execute(post)) {
            int statusCode = response.getStatusLine().getStatusCode();
            String responseBody = EntityUtils.toString(response.getEntity());
            logger.debug("Transcription Response Status Code: " + statusCode);
            logger.debug("Transcription Response Body: " + responseBody);

            if (statusCode != HttpServletResponse.SC_OK) {
                throw new IOException("Transcription API call failed: " + responseBody);
            }

            HttpEntity responseEntity = response.getEntity();
            String responseBodyText = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
            Map<String, Object> responseMap = objectMapper.readValue(responseBodyText, Map.class);
            transcription = (String) responseMap.get("text");
        } catch (ClientProtocolException e) {
            logger.error("ClientProtocolException while calling OpenAI API for transcription.", e);
            throw new IOException("ClientProtocolException: Transcription API call failed.", e);
        } catch (IOException e) {
            logger.error("IOException while calling OpenAI API for transcription.", e);
            throw new IOException("Transcription API call failed.", e);
        }

        return transcription;
    }

Hi there,

I got this to work and now code is not throws to ClientProtocolException with message: “Transcription API call failed.”. But unfortunately this configuration causes other problems like Atlasian Marketplace is not reachable anymore and there other SSL connection error.

First

sudo service confluence stop

Here is corrected configuration of server (with Apache 2 mod_proxy).

./conf/server.xml in Ubuntu 20.04 LTS

<Connector port="8090" connectionTimeout="20000" redirectPort="8443"
                   maxThreads="48" maxPostSize="16777216" minSpareThreads="10"
                   enableLookups="false" acceptCount="100" URIEncoding="UTF-8"
                   protocol="org.apache.coyote.http11.Http11NioProtocol"
                   scheme="https" secure="true" proxyName="www.mydomain.com" proxyPort="443"
                   disableUploadTimeout="true" 
                   keystoreFile="conf/keystore.jks"
                   keystorePass="mypassowrd"
        />
 
	<SSLHostConfig>
        	<Certificate certificateKeystoreFile="conf/keystore.jks"
                     certificateKeystorePassword="mypassword"
		     certificateKeyAlias="tomcat"
                     type="RSA" />
   	</SSLHostConfig>

mod_proxy setting on virtualhost SSL file

  ProxyPreserveHost On

  ProxyPass / http://127.0.0.1:8090/
  ProxyPassReverse / http://127.0.0.1:8090/

./bin/setenv.sh

# Set TSL trust zone
CATALINA_OPTS="-Djavax.net.ssl.trustStore=/opt/atlassian/confluence/conf/keystore.jks ${CATALINA_OPTS}"
CATALINA_OPTS="-Djavax.net.ssl.trustStorePassword=mypassword ${CATALINA_OPTS}"

Export certificate

keytool -export -alias tomcat -file tomcat.crt -keystore conf/keystore.jks

Import certificate

keytool -import -alias tomcat -file tomcat.crt -keystore conf/truststore.jks

After these execute

sudo service confluence start
sudo service apache2 restart