Class BaseAPIActionUtil
java.lang.Object
com.kingsrook.qqq.backend.module.api.actions.BaseAPIActionUtil
Base class for utility functions that make up the unique ways in which an
API can be implemented.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumenum of which HTTP Method the backend uses for Updates. -
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected voidaddApiKeyQueryParamToRequest(org.apache.http.client.methods.HttpRequestBase request) protected org.apache.http.impl.client.CloseableHttpClientBuild the default HttpClient used by the makeRequest methodprotected StringbuildQueryStringForDelete(QQueryFilter filter, List<Serializable> primaryKeys) method to build up delete string based on a given QFilter objectprotected StringbuildQueryStringForGet(QQueryFilter filter, Integer limit, Integer skip, Map<String, QFieldMetaData> fields) method to build up a query string based on a given QFilter objectprotected StringbuildQueryStringForUpdate(QTableMetaData table, List<QRecord> recordList) method to build up a query string for updates based on a given QFilter objectprotected StringbuildTableUrl(QTableMetaData table) Helper method to build the URL for a table.buildUrlSuffixForSingleRecordGet(Serializable primaryKey) Do a default query string for a single-record GET - e.g., a query for just 1 record.buildUrlSuffixForSingleRecordGet(Map<String, Serializable> uniqueKey) protected voidcheckForOAuthExpiredToken(QTableMetaData table, org.apache.http.client.methods.HttpRequestBase request, QHttpResponse response) protected org.apache.http.client.methods.HttpRequestBaseFor doing OAuth2 authentication, create a request for a token.doCount(QTableMetaData table, CountInput countInput) doDelete(QTableMetaData table, DeleteInput deleteInput) doGet(QTableMetaData table, GetInput getInput) doInsert(QTableMetaData table, InsertInput insertInput) doQuery(QTableMetaData table, QueryInput queryInput) OK - so - we will potentially make multiple GET calls to the backend, to fetch up to the full limit from the filter (and, if there is no limit in the filter, then we'll keep fetching until we stop getting results).doUpdate(QTableMetaData table, UpdateInput updateInput) protected org.apache.http.client.methods.CloseableHttpResponseexecuteHttpRequest(org.apache.http.client.methods.HttpRequestBase request, org.apache.http.impl.client.CloseableHttpClient httpClient) one-line method, factored out so mock/tests can overrideprotected org.apache.http.client.methods.CloseableHttpResponseexecuteOAuthTokenRequest(org.apache.http.impl.client.CloseableHttpClient client, org.apache.http.client.methods.HttpPost request) Deprecated.protected org.apache.http.client.methods.CloseableHttpResponseexecuteOAuthTokenRequest(org.apache.http.impl.client.CloseableHttpClient client, org.apache.http.client.methods.HttpRequestBase request) one-line method, factored out so mock/tests can overridegenerateOutboundApiLogRecord(org.apache.http.client.methods.HttpRequestBase request, QHttpResponse response) protected Stringprotected org.apache.logging.log4j.Levelprotected Integerprotected APITableBackendDetailsgetBackendDetails(QTableMetaData tableMetaData) Getter for backendMetaDataprotected StringgetBasicAuthenticationHeader(String apiKey) Helper method to create a value for an Authentication header, using just an apiKey - encoded as Basic + base64(apiKey)getBasicAuthenticationHeader(String username, String password) Helper method to create a value for an Authentication header, using just a username invalid input: '&' password - encoded as Basic + base64(username:password)protected static CharsetLet a subclass change what charset to use for entities (bodies) being posted/put/etc.protected intFor the HttpClientBuilder RequestConfig, specify its ConnectionRequestTimeout.protected intFor the HttpClientBuilder RequestConfig, specify its ConnectionTimeout.protected Stringprotected intprotected intprotected org.json.JSONObjectgetJsonObject(QHttpResponse response) protected intprotected intprotected intprotected longprotected QHttpResponsegetQHttpResponse(org.apache.http.HttpResponse response) protected intFor the HttpClientBuilder RequestConfig, specify its ConnectionRequestTimeout.protected BaseAPIActionUtil.UpdateHttpMethodprotected voidhandleCustomAuthorization(org.apache.http.client.methods.HttpRequestBase request) protected voidhandleResponseError(QTableMetaData table, org.apache.http.client.methods.HttpRequestBase request, QHttpResponse response) protected QRecordjsonObjectToRecord(org.json.JSONObject jsonObject, Map<String, QFieldMetaData> fields) protected voidlogOutboundApiCall(org.apache.http.client.methods.HttpRequestBase request, QHttpResponse response) protected voidlogRequestDetails(QTableMetaData table, org.apache.http.client.methods.HttpRequestBase request) makeRequest(QTableMetaData table, org.apache.http.client.methods.HttpRequestBase request) protected intprocessGetResponse(QTableMetaData table, QHttpResponse response, QueryOutput queryOutput) processGetResponseForCount(QTableMetaData table, QHttpResponse response) protected QRecordprocessPostResponse(QTableMetaData table, QRecord record, QHttpResponse response) processSingleRecordGetResponse(QTableMetaData table, QHttpResponse response) protected org.apache.http.entity.AbstractHttpEntityrecordsToEntity(QTableMetaData table, List<QRecord> recordList) Build an HTTP Entity (e.g., for a PUT or POST) from a list of QRecords.protected org.apache.http.entity.AbstractHttpEntityrecordToEntity(QTableMetaData table, QRecord record) Build an HTTP Entity (e.g., for a PUT or POST) from a QRecord.protected org.json.JSONObjectrecordToJsonObject(QTableMetaData table, QRecord record) Helper for recordToEntity - builds a basic JSON object.voidsetActionInput(AbstractTableActionInput actionInput) Setter for actionInputvoidsetBackendMetaData(APIBackendMetaData backendMetaData) Setter for backendMetaDatavoidsetSession(QSession session) Deprecated.voidsetupAdditionalHeaders(org.apache.http.client.methods.HttpRequestBase request) As part of making a request - set up additional headers.voidsetupAuthorizationInRequest(org.apache.http.client.methods.HttpRequestBase request) As part of making a request - set up its authorization header (not just strictly "Authorization", but whatever is needed for auth).protected voidsetupContentTypeInRequest(org.apache.http.client.methods.HttpRequestBase request) As part of making a request - set up its content-type header.protected booleanprotected voidthrowUnsupportedCriteriaField(QFilterCriteria criteria) protected voidprotected StringvoidvalidateResponse(QHttpResponse response, List<QRecord> recordList)
-
Field Details
-
backendMetaData
-
actionInput
-
-
Constructor Details
-
BaseAPIActionUtil
public BaseAPIActionUtil()
-
-
Method Details
-
doCount
- Throws:
QException
-
doGet
- Throws:
QException
-
doInsert
- Throws:
QException
-
doQuery
OK - so - we will potentially make multiple GET calls to the backend, to fetch up to the full limit from the filter (and, if there is no limit in the filter, then we'll keep fetching until we stop getting results). This is managed internally here by copying the limit into the originalLimit var. Then "limit" in this method becomes the api's "how many to fetch per page" parameter (either the originalLimit, or the api's standard limit). Then we break the loop (return from the method) either when: - we've fetch a total count >= the originalLimit - we got back less than a page full (e.g., we're at the end of the result set). - an async job was cancelled.- Throws:
QException
-
doUpdate
- Throws:
QException
-
doDelete
- Throws:
QException
-
validateResponse
- Throws:
QException
-
processGetResponseForCount
public Integer processGetResponseForCount(QTableMetaData table, QHttpResponse response) throws QException - Throws:
QException
-
processSingleRecordGetResponse
public QRecord processSingleRecordGetResponse(QTableMetaData table, QHttpResponse response) throws QException - Throws:
QException
-
processPostResponse
protected QRecord processPostResponse(QTableMetaData table, QRecord record, QHttpResponse response) throws QException - Throws:
QException
-
processGetResponse
protected int processGetResponse(QTableMetaData table, QHttpResponse response, QueryOutput queryOutput) throws QException - Throws:
QException
-
handleResponseError
protected void handleResponseError(QTableMetaData table, org.apache.http.client.methods.HttpRequestBase request, QHttpResponse response) throws QException - Throws:
QException
-
checkForOAuthExpiredToken
protected void checkForOAuthExpiredToken(QTableMetaData table, org.apache.http.client.methods.HttpRequestBase request, QHttpResponse response) throws OAuthExpiredTokenException - Throws:
OAuthExpiredTokenException
-
buildQueryStringForUpdate
protected String buildQueryStringForUpdate(QTableMetaData table, List<QRecord> recordList) throws QException method to build up a query string for updates based on a given QFilter object- Throws:
QException
-
buildQueryStringForGet
protected String buildQueryStringForGet(QQueryFilter filter, Integer limit, Integer skip, Map<String, QFieldMetaData> fields) throws QExceptionmethod to build up a query string based on a given QFilter object- Throws:
QException
-
buildQueryStringForDelete
protected String buildQueryStringForDelete(QQueryFilter filter, List<Serializable> primaryKeys) throws QException method to build up delete string based on a given QFilter object- Throws:
QException
-
buildUrlSuffixForSingleRecordGet
Do a default query string for a single-record GET - e.g., a query for just 1 record.- Throws:
QException
-
buildUrlSuffixForSingleRecordGet
public String buildUrlSuffixForSingleRecordGet(Map<String, Serializable> uniqueKey) throws QException- Throws:
QException
-
setupAuthorizationInRequest
public void setupAuthorizationInRequest(org.apache.http.client.methods.HttpRequestBase request) throws QException As part of making a request - set up its authorization header (not just strictly "Authorization", but whatever is needed for auth). Can be overridden if an API uses an authorization type we don't natively support.- Throws:
QException
-
addApiKeyQueryParamToRequest
protected void addApiKeyQueryParamToRequest(org.apache.http.client.methods.HttpRequestBase request) throws QException - Throws:
QException
-
getApiKey
- Throws:
QException
-
getUsernameAndPassword
- Throws:
QException
-
getOAuth2Token
- Throws:
QException
-
createOAuth2TokenRequest
protected org.apache.http.client.methods.HttpRequestBase createOAuth2TokenRequest() throws QExceptionFor doing OAuth2 authentication, create a request for a token.- Throws:
QException
-
getClientIdAndSecret
- Throws:
QException
-
getCharsetForEntity
Let a subclass change what charset to use for entities (bodies) being posted/put/etc. -
executeOAuthTokenRequest
protected org.apache.http.client.methods.CloseableHttpResponse executeOAuthTokenRequest(org.apache.http.impl.client.CloseableHttpClient client, org.apache.http.client.methods.HttpRequestBase request) throws IOException one-line method, factored out so mock/tests can override- Throws:
IOException
-
executeOAuthTokenRequest
@Deprecated protected org.apache.http.client.methods.CloseableHttpResponse executeOAuthTokenRequest(org.apache.http.impl.client.CloseableHttpClient client, org.apache.http.client.methods.HttpPost request) throws IOException Deprecated.one-line method, factored out so mock/tests can override Deprecated, in favor of more generic overload that takes HttpRequestBase- Throws:
IOException
-
setupContentTypeInRequest
protected void setupContentTypeInRequest(org.apache.http.client.methods.HttpRequestBase request) As part of making a request - set up its content-type header. -
getBasicAuthenticationHeader
-
setupAdditionalHeaders
public void setupAdditionalHeaders(org.apache.http.client.methods.HttpRequestBase request) As part of making a request - set up additional headers. Noop in base - meant to override in subclasses. -
getBasicAuthenticationHeader
-
buildTableUrl
Helper method to build the URL for a table. Can be overridden, if a particular API isn't just "base" + "tablePath". Note: you may want to look at the actionInput object, to help figure out what path you need, depending on your API. -
recordToEntity
protected org.apache.http.entity.AbstractHttpEntity recordToEntity(QTableMetaData table, QRecord record) throws IOException Build an HTTP Entity (e.g., for a PUT or POST) from a QRecord. Can be overridden if an API doesn't do a basic json object. Or, can override a helper method, such as recordToJsonObject.- Throws:
IOException
-
recordsToEntity
protected org.apache.http.entity.AbstractHttpEntity recordsToEntity(QTableMetaData table, List<QRecord> recordList) throws QException Build an HTTP Entity (e.g., for a PUT or POST) from a list of QRecords. Can be overridden if an API doesn't do a basic json object. Or, can override a helper method, such as recordToJsonObject.- Throws:
QException
-
recordToJsonObject
Helper for recordToEntity - builds a basic JSON object. Can be overridden if an API doesn't do a basic json object. -
jsonObjectToRecord
protected QRecord jsonObjectToRecord(org.json.JSONObject jsonObject, Map<String, QFieldMetaData> fields) throws QException- Throws:
QException
-
getJsonObject
- Throws:
QException
-
logRequestDetails
protected void logRequestDetails(QTableMetaData table, org.apache.http.client.methods.HttpRequestBase request) throws QException - Throws:
QException
-
getQHttpResponse
- Throws:
Exception
-
makeRequest
public QHttpResponse makeRequest(QTableMetaData table, org.apache.http.client.methods.HttpRequestBase request) throws QException - Throws:
QException
-
buildHttpClient
protected org.apache.http.impl.client.CloseableHttpClient buildHttpClient()Build the default HttpClient used by the makeRequest method -
shouldBeRetryableServerErrorException
-
executeHttpRequest
protected org.apache.http.client.methods.CloseableHttpResponse executeHttpRequest(org.apache.http.client.methods.HttpRequestBase request, org.apache.http.impl.client.CloseableHttpClient httpClient) throws IOException one-line method, factored out so mock/tests can override- Throws:
IOException
-
logOutboundApiCall
protected void logOutboundApiCall(org.apache.http.client.methods.HttpRequestBase request, QHttpResponse response) -
generateOutboundApiLogRecord
public OutboundAPILog generateOutboundApiLogRecord(org.apache.http.client.methods.HttpRequestBase request, QHttpResponse response) -
getBackendDetails
-
getFieldBackendName
-
urlEncode
-
getBackendMetaData
Getter for backendMetaData -
setBackendMetaData
Setter for backendMetaData -
setActionInput
Setter for actionInput -
setSession
Deprecated.Setter for session -
throwUnsupportedCriteriaField
- Throws:
QUserFacingException
-
throwUnsupportedCriteriaOperator
protected void throwUnsupportedCriteriaOperator(QFilterCriteria criteria) throws QUserFacingException - Throws:
QUserFacingException
-
getMillisToSleepAfterEveryCall
protected long getMillisToSleepAfterEveryCall() -
getInitialRateLimitBackoffMillis
protected int getInitialRateLimitBackoffMillis() -
getInitialServerErrorBackoffMillis
protected int getInitialServerErrorBackoffMillis() -
getMaxAllowedRateLimitErrors
protected int getMaxAllowedRateLimitErrors() -
getMaxAllowedServerErrors
protected int getMaxAllowedServerErrors() -
getApiStandardLimit
-
getUpdateMethod
-
getMaxResponseMessageLengthForLog
protected int getMaxResponseMessageLengthForLog() -
getConnectionTimeoutMillis
protected int getConnectionTimeoutMillis()For the HttpClientBuilder RequestConfig, specify its ConnectionTimeout. See - https://www.baeldung.com/httpclient-timeout - https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/org/apache/hc/client5/http/config/RequestConfig.Builder.html -
getConnectionRequestTimeoutMillis
protected int getConnectionRequestTimeoutMillis()For the HttpClientBuilder RequestConfig, specify its ConnectionRequestTimeout. See - https://www.baeldung.com/httpclient-timeout - https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/org/apache/hc/client5/http/config/RequestConfig.Builder.html -
getSocketTimeoutMillis
protected int getSocketTimeoutMillis()For the HttpClientBuilder RequestConfig, specify its ConnectionRequestTimeout. See - https://www.baeldung.com/httpclient-timeout - https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/org/apache/hc/client5/http/config/RequestConfig.Builder.html -
handleCustomAuthorization
protected void handleCustomAuthorization(org.apache.http.client.methods.HttpRequestBase request) throws QException - Throws:
QException
-
getAPIResponseLogLevel
- Throws:
QException
-