com.sap.cloud.sdk.s4hana.connectivity.Query Maven / Gradle / Ivy
/*
* Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved.
*/
package com.sap.cloud.sdk.s4hana.connectivity;
import java.time.Duration;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.sap.cloud.sdk.cloudplatform.connectivity.Header;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationNotFoundException;
import com.sap.cloud.sdk.s4hana.connectivity.exception.QueryExecutionException;
import com.sap.cloud.sdk.s4hana.connectivity.exception.QuerySerializationException;
import lombok.Getter;
import lombok.Setter;
/**
* Common interface for ERP queries.
*/
public abstract class Query, QueryResultT extends QueryResult>
{
private static final AtomicLong requestIdCounter = new AtomicLong();
/**
* Represents an identifier that allows to correlate queries between the Cloud cloudplatform and the ERP.
*
* Important: The identifier does not provide any guarantees with respect to persistence across the
* application lifecycle. In particular, the identifier will be reset to 1 when restarting the application.
*/
@Getter
private final long requestId;
/**
* Custom execution duration threshold indicating that the query is long running.
*/
@Nullable
@Getter
@Setter
private Duration longRunningRequestThreshold = null;
/**
* Set of HTTP headers to send to the underlying query executor. Note that these headers will only be added to
* HTTP-based queries.
*/
@Nonnull
@Getter
private final List customHttpHeaders = new LinkedList<>();
protected Query()
{
requestId = requestIdCounter.incrementAndGet();
}
/**
* @return The method name that originally constructed this ERP query. This information is used for debugging.
*/
@Nonnull
public abstract String getConstructedByMethod();
/**
* @return A optional String representation of the data being access by this query. If present, an audit log entry
* is written using the given data.
*/
@Nullable
public String getReadAccessData()
{
return null;
}
@SuppressWarnings( "unchecked" )
@Nonnull
protected QueryT getThis()
{
return (QueryT) this;
}
/**
* @deprecated Use {@link #getCustomHttpHeaders()} instead. Will be removed in one of the next releases.
*/
@Deprecated
@Nonnull
public List getHeaderParameters()
{
return customHttpHeaders;
}
/**
* Fluent method which adds a custom HTTP header to this query. Note that these headers will only be added to
* HTTP-based queries. If the header with the provided name already exists, the value is overwritten.
*
* @param name
* Header parameter name.
* @param value
* Header parameter value.
*
* @return The same {@link Query} instance, so that this method can be used again in a fluent API style.
*/
@Nonnull
public QueryT withCustomHttpHeader( @Nonnull final String name, @Nullable final String value )
{
return withCustomHttpHeader(new Header(name, value));
}
/**
* Fluent method which adds a custom header to this query. Note that these headers will only be added to HTTP-based
* queries. If the header with the provided name already exists, the value is overwritten.
*
* @param header
* The custom header.
*
* @return The same {@link Query} instance, so that this method can be used again in a fluent API style.
*/
@Nonnull
public QueryT withCustomHttpHeader( @Nonnull final Header header )
{
customHttpHeaders.add(header);
return getThis();
}
/**
* Fluent method which adds the custom headers from another query into this query. Note that these headers will only
* be added to HTTP-based queries. If any headers in the other query already exist in this query, the values will be
* overwritten.
*
* @param otherQuery
* Other query to get header parameters from.
*
* @return The same {@link Query} instance, so that this method can be used again in a fluent API style.
*/
@Nonnull
public QueryT withSameCustomHttpHeadersAs( @Nonnull final Query, ?> otherQuery )
{
customHttpHeaders.addAll(otherQuery.getCustomHttpHeaders());
return getThis();
}
/**
* Executes a given query using the given {@link ErpConfigContext}.
*
* @param configContext
* The {@link ErpConfigContext} to be used for query execution.
*
* @throws QuerySerializationException
* If there is an issue while serializing the query.
*
* @throws QueryExecutionException
* If there is an issue while executing the query.
*
* @throws DestinationNotFoundException
* If no destination with the name specified in the {@link ErpConfigContext} can be found.
*
* @throws DestinationAccessException
* If there is an issue while accessing destination information.
*/
@Nonnull
public abstract QueryResultT execute( @Nonnull final ErpConfigContext configContext )
throws QuerySerializationException,
QueryExecutionException,
DestinationNotFoundException,
DestinationAccessException;
/**
* Executes a given query using the default {@link ErpConfigContext}. The default {@link ErpConfigContext} can be
* instantiated with {@code new ErpConfigContext()}.
*
* @throws QuerySerializationException
* If there is an issue while serializing the query.
*
* @throws QueryExecutionException
* If there is an issue while executing the query.
*
* @throws DestinationNotFoundException
* If no destination with the name specified in the {@link ErpConfigContext} can be found.
*
* @throws DestinationAccessException
* If there is an issue while accessing destination information.
*/
@Nonnull
public QueryResultT execute()
throws QuerySerializationException,
QueryExecutionException,
DestinationNotFoundException,
DestinationAccessException
{
return execute(new ErpConfigContext());
}
}