Example usage for com.squareup.okhttp OkHttpClient newCall

List of usage examples for com.squareup.okhttp OkHttpClient newCall

Introduction

In this page you can find the example usage for com.squareup.okhttp OkHttpClient newCall.

Prototype

public Call newCall(Request request) 

Source Link

Document

Prepares the request to be executed at some point in the future.

Usage

From source file:org.apache.nifi.processors.att.m2x.PutM2XStream.java

License:Apache License

@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException {
    final FlowFile flowFile = session.get();
    if (flowFile == null) {
        return;/*from  ww  w . ja v  a2 s  .co  m*/
    }

    final ProcessorLog logger = getLogger();
    final OkHttpClient httpClient = getHttpClient();
    final StateManager stateManager = context.getStateManager();
    final String apiKey = context.getProperty(M2X_API_KEY).getValue();
    final String apiUrl = context.getProperty(M2X_API_URL).getValue();
    final String deviceId = context.getProperty(M2X_DEVICE_ID).getValue();
    final String streamName = context.getProperty(M2X_STREAM_NAME).getValue();
    final String streamType = context.getProperty(M2X_STREAM_TYPE).getValue();
    final String streamUrl = new StringBuilder().append(apiUrl.replaceAll("/*$", "")).append("/devices/")
            .append(deviceId).append("/streams/").append(streamName).append("/value").toString();

    try {
        final AtomicReference<String> postBodyRef = new AtomicReference<>();
        session.read(flowFile, new InputStreamCallback() {
            @Override
            public void process(InputStream is) {
                try {
                    String timestamp = flowFile.getAttribute("m2x.stream.value.timestamp");
                    if (StringUtils.isEmpty(timestamp)) {
                        timestamp = ISODateTimeFormat.dateTime().print(flowFile.getEntryDate());
                    }
                    final String value = IOUtils.toString(is, StandardCharsets.UTF_8);

                    final M2XStreamValue m2xValue = new M2XStreamValue();
                    m2xValue.setValue(value);
                    m2xValue.setTimestamp(timestamp);

                    final ObjectMapper mapper = new ObjectMapper();
                    mapper.registerModule(new JodaModule());
                    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

                    final String postBody = mapper.writeValueAsString(m2xValue);
                    logger.warn("POST body is {}", new Object[] { postBody });
                    postBodyRef.set(postBody);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        });

        final String postBody = postBodyRef.get();
        if (StringUtils.isEmpty(postBody)) {
            logger.error("FlowFile {} contents didn't produce a valid M2X stream value",
                    new Object[] { flowFile });
            session.transfer(flowFile, REL_FAILURE);
            return;
        }

        final Request request = new Request.Builder().url(streamUrl).addHeader("X-M2X-KEY", apiKey)
                .put(RequestBody.create(MEDIA_TYPE_JSON, postBody)).build();
        final Response response = httpClient.newCall(request).execute();

        if (!response.isSuccessful()) {
            logger.error(response.message());
            context.yield();
            session.penalize(flowFile);
            return;
        }
    } catch (IOException e) {
        logger.error(e.getMessage(), e);
        context.yield();
        session.penalize(flowFile);
        return;
    }

    session.transfer(flowFile, REL_SUCCESS);
}

From source file:org.apache.nifi.processors.standard.InvokeHTTP.java

License:Apache License

@Override
public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
    OkHttpClient okHttpClient = okHttpClientAtomicReference.get();

    FlowFile requestFlowFile = session.get();

    // Checking to see if the property to put the body of the response in an attribute was set
    boolean putToAttribute = context.getProperty(PROP_PUT_OUTPUT_IN_ATTRIBUTE).isSet();
    if (requestFlowFile == null) {
        if (context.hasNonLoopConnection()) {
            return;
        }/*from  w w w .j a v a 2 s .c  om*/

        String request = context.getProperty(PROP_METHOD).evaluateAttributeExpressions().getValue()
                .toUpperCase();
        if ("POST".equals(request) || "PUT".equals(request) || "PATCH".equals(request)) {
            return;
        } else if (putToAttribute) {
            requestFlowFile = session.create();
        }
    }

    // Setting some initial variables
    final int maxAttributeSize = context.getProperty(PROP_PUT_ATTRIBUTE_MAX_LENGTH).asInteger();
    final ComponentLog logger = getLogger();

    // Every request/response cycle has a unique transaction id which will be stored as a flowfile attribute.
    final UUID txId = UUID.randomUUID();

    FlowFile responseFlowFile = null;
    try {
        // read the url property from the context
        final String urlstr = trimToEmpty(
                context.getProperty(PROP_URL).evaluateAttributeExpressions(requestFlowFile).getValue());
        final URL url = new URL(urlstr);

        Request httpRequest = configureRequest(context, session, requestFlowFile, url);

        // log request
        logRequest(logger, httpRequest);

        // emit send provenance event if successfully sent to the server
        if (httpRequest.body() != null) {
            session.getProvenanceReporter().send(requestFlowFile, url.toExternalForm(), true);
        }

        final long startNanos = System.nanoTime();
        Response responseHttp = okHttpClient.newCall(httpRequest).execute();

        // output the raw response headers (DEBUG level only)
        logResponse(logger, url, responseHttp);

        // store the status code and message
        int statusCode = responseHttp.code();
        String statusMessage = responseHttp.message();

        if (statusCode == 0) {
            throw new IllegalStateException("Status code unknown, connection hasn't been attempted.");
        }

        // Create a map of the status attributes that are always written to the request and response FlowFiles
        Map<String, String> statusAttributes = new HashMap<>();
        statusAttributes.put(STATUS_CODE, String.valueOf(statusCode));
        statusAttributes.put(STATUS_MESSAGE, statusMessage);
        statusAttributes.put(REQUEST_URL, url.toExternalForm());
        statusAttributes.put(TRANSACTION_ID, txId.toString());

        if (requestFlowFile != null) {
            requestFlowFile = session.putAllAttributes(requestFlowFile, statusAttributes);
        }

        // If the property to add the response headers to the request flowfile is true then add them
        if (context.getProperty(PROP_ADD_HEADERS_TO_REQUEST).asBoolean() && requestFlowFile != null) {
            // write the response headers as attributes
            // this will overwrite any existing flowfile attributes
            requestFlowFile = session.putAllAttributes(requestFlowFile,
                    convertAttributesFromHeaders(url, responseHttp));
        }

        boolean outputBodyToRequestAttribute = (!isSuccess(statusCode) || putToAttribute)
                && requestFlowFile != null;
        boolean outputBodyToResponseContent = (isSuccess(statusCode) && !putToAttribute)
                || context.getProperty(PROP_OUTPUT_RESPONSE_REGARDLESS).asBoolean();
        ResponseBody responseBody = responseHttp.body();
        boolean bodyExists = responseBody != null;

        InputStream responseBodyStream = null;
        SoftLimitBoundedByteArrayOutputStream outputStreamToRequestAttribute = null;
        TeeInputStream teeInputStream = null;
        try {
            responseBodyStream = bodyExists ? responseBody.byteStream() : null;
            if (responseBodyStream != null && outputBodyToRequestAttribute && outputBodyToResponseContent) {
                outputStreamToRequestAttribute = new SoftLimitBoundedByteArrayOutputStream(maxAttributeSize);
                teeInputStream = new TeeInputStream(responseBodyStream, outputStreamToRequestAttribute);
            }

            if (outputBodyToResponseContent) {
                /*
                 * If successful and putting to response flowfile, store the response body as the flowfile payload
                 * we include additional flowfile attributes including the response headers and the status codes.
                 */

                // clone the flowfile to capture the response
                if (requestFlowFile != null) {
                    responseFlowFile = session.create(requestFlowFile);
                } else {
                    responseFlowFile = session.create();
                }

                // write attributes to response flowfile
                responseFlowFile = session.putAllAttributes(responseFlowFile, statusAttributes);

                // write the response headers as attributes
                // this will overwrite any existing flowfile attributes
                responseFlowFile = session.putAllAttributes(responseFlowFile,
                        convertAttributesFromHeaders(url, responseHttp));

                // transfer the message body to the payload
                // can potentially be null in edge cases
                if (bodyExists) {
                    // write content type attribute to response flowfile if it is available
                    if (responseBody.contentType() != null) {
                        responseFlowFile = session.putAttribute(responseFlowFile,
                                CoreAttributes.MIME_TYPE.key(), responseBody.contentType().toString());
                    }
                    if (teeInputStream != null) {
                        responseFlowFile = session.importFrom(teeInputStream, responseFlowFile);
                    } else {
                        responseFlowFile = session.importFrom(responseBodyStream, responseFlowFile);
                    }

                    // emit provenance event
                    final long millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
                    if (requestFlowFile != null) {
                        session.getProvenanceReporter().fetch(responseFlowFile, url.toExternalForm(), millis);
                    } else {
                        session.getProvenanceReporter().receive(responseFlowFile, url.toExternalForm(), millis);
                    }
                }
            }

            // if not successful and request flowfile is not null, store the response body into a flowfile attribute
            if (outputBodyToRequestAttribute && bodyExists) {
                String attributeKey = context.getProperty(PROP_PUT_OUTPUT_IN_ATTRIBUTE)
                        .evaluateAttributeExpressions(requestFlowFile).getValue();
                if (attributeKey == null) {
                    attributeKey = RESPONSE_BODY;
                }
                byte[] outputBuffer;
                int size;

                if (outputStreamToRequestAttribute != null) {
                    outputBuffer = outputStreamToRequestAttribute.getBuffer();
                    size = outputStreamToRequestAttribute.size();
                } else {
                    outputBuffer = new byte[maxAttributeSize];
                    size = StreamUtils.fillBuffer(responseBodyStream, outputBuffer, false);
                }
                String bodyString = new String(outputBuffer, 0, size,
                        getCharsetFromMediaType(responseBody.contentType()));
                requestFlowFile = session.putAttribute(requestFlowFile, attributeKey, bodyString);

                final long millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
                session.getProvenanceReporter().modifyAttributes(requestFlowFile,
                        "The " + attributeKey
                                + " has been added. The value of which is the body of a http call to "
                                + url.toExternalForm() + ". It took " + millis + "millis,");
            }
        } finally {
            if (outputStreamToRequestAttribute != null) {
                outputStreamToRequestAttribute.close();
                outputStreamToRequestAttribute = null;
            }
            if (teeInputStream != null) {
                teeInputStream.close();
                teeInputStream = null;
            } else if (responseBodyStream != null) {
                responseBodyStream.close();
                responseBodyStream = null;
            }
        }

        route(requestFlowFile, responseFlowFile, session, context, statusCode);
    } catch (final Exception e) {
        // penalize or yield
        if (requestFlowFile != null) {
            logger.error("Routing to {} due to exception: {}", new Object[] { REL_FAILURE.getName(), e }, e);
            requestFlowFile = session.penalize(requestFlowFile);
            requestFlowFile = session.putAttribute(requestFlowFile, EXCEPTION_CLASS, e.getClass().getName());
            requestFlowFile = session.putAttribute(requestFlowFile, EXCEPTION_MESSAGE, e.getMessage());
            // transfer original to failure
            session.transfer(requestFlowFile, REL_FAILURE);
        } else {
            logger.error("Yielding processor due to exception encountered as a source processor: {}", e);
            context.yield();
        }

        // cleanup response flowfile, if applicable
        try {
            if (responseFlowFile != null) {
                session.remove(responseFlowFile);
            }
        } catch (final Exception e1) {
            logger.error("Could not cleanup response flowfile due to exception: {}", new Object[] { e1 }, e1);
        }
    }
}

From source file:org.dataconservancy.cos.packaging.OsfContentProvider.java

License:Apache License

/**
 * Create a FileInfo that points to file content present at a URL.
 * The content from the URL is downloaded and stored in a temporary file.
 * <p>/*from  w  w  w .j av a  2 s .co  m*/
 * The logical name of the file represented in the FileInfo is the {@code name} parameter.
 * </p>
 *
 * @param filename the logical name of the content represented by the returned {@code FileInfo}
 * @param contentUrl resolvable URL to the content
 * @return populated FileInfo
 * @throws RuntimeException if the content cannot be downloaded or saved to a temporary file
 */
private FileInfo contentFromUrl(String filename, String contentUrl) {
    LOG.debug("  Retrieving '{}' content from '{}'", filename, contentUrl);

    File outFile;
    try {
        outFile = new File(temporaryDirectory, filename);
        byte[] data = this.resolver.resolve(contentUrl);
        if (data == null || data.length == 0) {
            // We actually don't know receiving zero bytes is an error, because the file to be retrieved at
            // 'contentUrl' may be in actuality, a zero-length file.  The 'Content-Length' header would let us
            // know this, but we don't have access to the HTTP headers.
            OkHttpClient client = cxt.getBean("okHttpClient", OkHttpClient.class);
            Request head = new Request.Builder().head().url(contentUrl).build();
            Integer contentLength = Integer
                    .parseInt(client.newCall(head).execute().header("Content-Length", "-1"));
            if (contentLength > 0) {
                throw new RuntimeException("Unable to retrieve content from '" + contentUrl + "': Expected "
                        + contentLength + " bytes but received 0 bytes.");
            }
        }
        IOUtils.write(data, new FileOutputStream(outFile));
    } catch (Exception e) {
        throw new RuntimeException(e.getMessage(), e);
    }

    FileInfo info = new FileInfo(outFile.toPath());
    info.setIsFile(true);
    return info;
}

From source file:org.eyeseetea.malariacare.network.NetworkUtils.java

License:Open Source License

/**
 * Pushes data to DHIS Server//from   www  . j  a  v  a2  s . c o m
 * @param data
 */
public JSONObject pushData(JSONObject data) throws Exception {
    Response response = null;

    final String DHIS_URL = getDhisURL() + DHIS_PUSH_API;

    OkHttpClient client = UnsafeOkHttpsClientFactory.getUnsafeOkHttpClient();
    client.setConnectTimeout(30, TimeUnit.SECONDS); // connect timeout
    client.setReadTimeout(30, TimeUnit.SECONDS); // socket timeout
    client.setWriteTimeout(30, TimeUnit.SECONDS); // write timeout
    client.setRetryOnConnectionFailure(false); // Cancel retry on failure
    BasicAuthenticator basicAuthenticator = new BasicAuthenticator();
    client.setAuthenticator(basicAuthenticator);

    Log.d(TAG, "Url" + DHIS_URL + "");
    RequestBody body = RequestBody.create(JSON, data.toString());
    Request request = new Request.Builder()
            .header(basicAuthenticator.AUTHORIZATION_HEADER, basicAuthenticator.getCredentials()).url(DHIS_URL)
            .post(body).build();

    response = client.newCall(request).execute();
    if (!response.isSuccessful()) {
        Log.e(TAG, "pushData (" + response.code() + "): " + response.body().string());
        throw new IOException(response.message());
    }
    return parseResponse(response.body().string());
}

From source file:org.eyeseetea.malariacare.network.NetworkUtils.java

License:Open Source License

/**
 * Pull data from DHIS Server//  ww  w.  ja va  2  s.c  o m
 * @param data
 */
public JSONObject getData(String data) throws Exception {
    Response response = null;

    final String DHIS_URL = getDhisURL() + DHIS_PULL_API + data;

    OkHttpClient client = UnsafeOkHttpsClientFactory.getUnsafeOkHttpClient();

    BasicAuthenticator basicAuthenticator = new BasicAuthenticator();
    client.setAuthenticator(basicAuthenticator);

    Log.d(TAG, "Url" + DHIS_URL + "");
    Request request = new Request.Builder()
            .header(basicAuthenticator.AUTHORIZATION_HEADER, basicAuthenticator.getCredentials()).url(DHIS_URL)
            .get().build();

    response = client.newCall(request).execute();
    if (!response.isSuccessful()) {
        Log.e(TAG, "getData (" + response.code() + "): " + response.body().string());
        throw new IOException(response.message());
    }
    return parseResponse(response.body().string());
}

From source file:org.eyeseetea.malariacare.network.NetworkUtils.java

License:Open Source License

/**
 * Call to DHIS Server/* ww  w. j  a va2 s  . c  o  m*/
 * @param data
 * @param url
 */
public Response executeCall(JSONObject data, String url, String method) throws IOException {
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext);
    final String DHIS_URL = sharedPreferences.getString(applicationContext.getString(R.string.dhis_url),
            applicationContext.getString(R.string.login_info_dhis_default_server_url)) + url;

    OkHttpClient client = UnsafeOkHttpsClientFactory.getUnsafeOkHttpClient();

    client.setConnectTimeout(30, TimeUnit.SECONDS); // connect timeout
    client.setReadTimeout(30, TimeUnit.SECONDS); // socket timeout
    client.setWriteTimeout(30, TimeUnit.SECONDS); // write timeout
    client.setRetryOnConnectionFailure(false); // Cancel retry on failure

    BasicAuthenticator basicAuthenticator = new BasicAuthenticator();
    client.setAuthenticator(basicAuthenticator);

    Request.Builder builder = new Request.Builder()
            .header(basicAuthenticator.AUTHORIZATION_HEADER, basicAuthenticator.getCredentials()).url(DHIS_URL);

    switch (method) {
    case "POST":
        RequestBody postBody = RequestBody.create(JSON, data.toString());
        builder.post(postBody);
        break;
    case "PUT":
        RequestBody putBody = RequestBody.create(JSON, data.toString());
        builder.put(putBody);
        break;
    case "PATCH":
        RequestBody patchBody = RequestBody.create(JSON, data.toString());
        builder.patch(patchBody);
        break;
    case "GET":
        builder.get();
        break;
    }

    Request request = builder.build();
    return client.newCall(request).execute();
}

From source file:org.eyeseetea.malariacare.network.PushClient.java

License:Open Source License

/**
 * Pushes data to DHIS Server/*from  w w  w.  ja va  2  s.c  o m*/
 * @param data
 */
private JSONObject pushData(JSONObject data) throws Exception {
    Response response = null;

    final String DHIS_URL = getDhisURL();

    OkHttpClient client = UnsafeOkHttpsClientFactory.getUnsafeOkHttpClient();

    BasicAuthenticator basicAuthenticator = new BasicAuthenticator();
    client.setAuthenticator(basicAuthenticator);

    RequestBody body = RequestBody.create(JSON, data.toString());
    Request request = new Request.Builder()
            .header(basicAuthenticator.AUTHORIZATION_HEADER, basicAuthenticator.getCredentials()).url(DHIS_URL)
            .post(body).build();

    response = client.newCall(request).execute();
    if (!response.isSuccessful()) {
        Log.e(TAG, "pushData (" + response.code() + "): " + response.body().string());
        throw new IOException(response.message());
    }
    return parseResponse(response.body().string());
}

From source file:org.eyeseetea.malariacare.network.ServerAPIController.java

License:Open Source License

/**
 * Call to DHIS Server/*from  w  w  w. j  av a  2 s . c om*/
 * @param data
 * @param url
 */
static Response executeCall(JSONObject data, String url, String method) throws IOException {
    final String DHIS_URL = url;

    OkHttpClient client = UnsafeOkHttpsClientFactory.getUnsafeOkHttpClient();

    BasicAuthenticator basicAuthenticator = new BasicAuthenticator();
    client.setAuthenticator(basicAuthenticator);

    Request.Builder builder = new Request.Builder()
            .header(basicAuthenticator.AUTHORIZATION_HEADER, basicAuthenticator.getCredentials()).url(DHIS_URL);

    switch (method) {
    case "POST":
        RequestBody postBody = RequestBody.create(JSON, data.toString());
        builder.post(postBody);
        break;
    case "PUT":
        RequestBody putBody = RequestBody.create(JSON, data.toString());
        builder.put(putBody);
        break;
    case "PATCH":
        RequestBody patchBody = RequestBody.create(JSON, data.toString());
        builder.patch(patchBody);
        break;
    case "GET":
        builder.get();
        break;
    }

    Request request = builder.build();
    return client.newCall(request).execute();
}

From source file:org.fuse.hawkular.agent.MonitorService.java

License:Apache License

private void waitForHawkularServer() throws Exception {
    OkHttpClient httpclient = this.httpClientBuilder.getHttpClient();

    String statusUrl = Util.getContextUrlString(subsystemConfiguration.getStorageAdapter().getUrl(),
            subsystemConfiguration.getStorageAdapter().getMetricsContext()).append("status").toString();
    Request request = this.httpClientBuilder.buildJsonGetRequest(statusUrl, null);
    while (true) {
        Response response = null;
        try {//from  ww w  .  ja  v  a  2s .c  o m
            response = httpclient.newCall(request).execute();
            if (response.code() != 200) {
                log.debugf("Hawkular Metrics is not ready yet: %d/%s", response.code(), response.message());
            } else {
                log.debugf("Hawkular Metrics is ready: %s", response.body().string());
                break;
            }
        } catch (Exception e) {
            log.debugf("Hawkular Metrics is not ready yet: %s", e.toString());
        } finally {
            if (response != null) {
                response.body().close();
            }
        }
        Thread.sleep(5000L);
    }

    if (this.subsystemConfiguration.getStorageAdapter().getType().toString().equals("HAWKULAR")) {
        statusUrl = Util
                .getContextUrlString(subsystemConfiguration.getStorageAdapter().getUrl(),
                        subsystemConfiguration.getStorageAdapter().getInventoryContext())
                .append("status").toString();
        request = this.httpClientBuilder.buildJsonGetRequest(statusUrl, null);
        while (true) {
            Response response = null;
            try {
                response = httpclient.newCall(request).execute();
                if (response.code() != 200) {
                    log.debugf("Hawkular Inventory is not ready yet: %d/%s", response.code(),
                            response.message());
                } else {
                    log.debugf("Hawkular Inventory is ready: %s", response.body().string());
                    break;
                }
            } catch (Exception e) {
                log.debugf("Hawkular Inventory is not ready yet: %s", e.toString());
            } finally {
                if (response != null) {
                    response.body().close();
                }
            }
            Thread.sleep(5000L);
        }
    }
}

From source file:org.fuse.hawkular.agent.MonitorService.java

License:Apache License

/**
 * Registers the feed with the Hawkular system under the given tenant.
 * Note, it is OK to re-register the same feed/tenant combinations.
 *
 * If retryMillis > 0 then this will not return until the feed is properly registered.
 * If the Hawkular server is not up, this could mean we are stuck here for a long time.
 *
 * @param tenantId the feed is registered under the given tenantId
 * @param retryMillis if >0 the amount of millis to elapse before retrying
 * @throws Exception if failed to register feed
 *///  w w w .j a  va2  s .  co m
public void registerFeed(String tenantId, int retryMillis) throws Exception {
    // get the payload in JSON format
    Feed.Blueprint feedPojo = new Feed.Blueprint(this.feedId, null);
    String jsonPayload = Util.toJson(feedPojo);

    // build the REST URL...
    // start with the protocol, host, and port, plus context
    StringBuilder url = Util.getContextUrlString(subsystemConfiguration.getStorageAdapter().getUrl(),
            subsystemConfiguration.getStorageAdapter().getInventoryContext());

    // rest of the URL says we want the feeds API
    url.append("entity/feed");

    // now send the REST requests - one for each tenant to register
    OkHttpClient httpclient = this.httpClientBuilder.getHttpClient();

    Map<String, String> header = Collections.singletonMap("Hawkular-Tenant", tenantId);
    Request request = this.httpClientBuilder.buildJsonPostRequest(url.toString(), header, jsonPayload);

    boolean keepRetrying = (retryMillis > 0);
    do {
        try {
            // note that we retry if newCall.execute throws an exception (assuming we were told to retry)
            Response httpResponse = httpclient.newCall(request).execute();

            try {
                // HTTP status of 201 means success; 409 means it already exists, anything else is an error
                if (httpResponse.code() == 201) {
                    keepRetrying = false;
                    final String feedObjectFromServer = httpResponse.body().string();
                    final Feed feed = Util.fromJson(feedObjectFromServer, Feed.class);
                    if (this.feedId.equals(feed.getId())) {
                        log.infoUsingFeedId(feed.getId(), tenantId);
                    } else {
                        // do not keep retrying - this is a bad error; we need to abort
                        log.errorUnwantedFeedId(feed.getId(), this.feedId, tenantId);
                        throw new Exception(String.format("Received unwanted feed [%s]", feed.getId()));
                    }
                } else if (httpResponse.code() == 409) {
                    keepRetrying = false;
                    log.infoFeedIdAlreadyRegistered(this.feedId, tenantId);
                } else if (httpResponse.code() == 404) {
                    // the server is probably just starting to come up - wait for it if we were told to retry
                    keepRetrying = (retryMillis > 0);
                    throw new Exception(String.format("Is the Hawkular Server booting up? (%d=%s)",
                            httpResponse.code(), httpResponse.message()));
                } else {
                    // futile to keep retrying and getting the same 500 or whatever error
                    keepRetrying = false;
                    throw new Exception(String.format("status-code=[%d], reason=[%s]", httpResponse.code(),
                            httpResponse.message()));
                }
            } finally {
                httpResponse.body().close();
            }
        } catch (Exception e) {
            log.warnCannotRegisterFeed(this.feedId, tenantId, request.urlString(), e.toString());
            if (keepRetrying) {
                Thread.sleep(retryMillis);
            } else {
                throw e;
            }
        }
    } while (keepRetrying);
}