All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.sap.cds.mtx.impl.AbstractSidecarAccess Maven / Gradle / Ivy
/*
* ----------------------------------------------------------------
* © 2019-2021 SAP SE or an SAP affiliate company. All rights reserved.
* ----------------------------------------------------------------
*
*/
package com.sap.cds.mtx.impl;
import static org.apache.http.HttpStatus.SC_BAD_GATEWAY;
import static org.apache.http.HttpStatus.SC_GATEWAY_TIMEOUT;
import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.apache.http.HttpStatus.SC_NOT_FOUND;
import static org.apache.http.HttpStatus.SC_NOT_MODIFIED;
import static org.apache.http.HttpStatus.SC_NO_CONTENT;
import static org.apache.http.HttpStatus.SC_OK;
import static org.apache.http.HttpStatus.SC_SERVICE_UNAVAILABLE;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.IntFunction;
import org.apache.http.HttpHeaders;
import com.google.common.base.Strings;
import com.sap.cds.CdsCommunicationException;
import com.sap.cds.mtx.ModelId;
import com.sap.cloud.mt.tools.api.RequestEnhancer;
import com.sap.cloud.mt.tools.api.ResilienceConfig;
import com.sap.cloud.mt.tools.api.ServiceCall;
import com.sap.cloud.mt.tools.api.ServiceEndpoint;
import com.sap.cloud.mt.tools.api.ServiceResponse;
import com.sap.cloud.mt.tools.exception.InternalException;
import com.sap.cloud.mt.tools.exception.ServiceException;
public abstract class AbstractSidecarAccess {
protected static final String APPLICATION_JSON = "application/json";
protected final ServiceEndpoint csnEndpoint;
protected final ServiceEndpoint edmxEndpoint;
protected final ServiceEndpoint i18nEndpoint;
protected RequestEnhancer requestEnhancer;
/**
* @param requestEnhancer Adds information to http request, for example for authentication and authority
* @param resilienceConfig Parameters like number of retries, wait between
* retries, ..
*/
protected AbstractSidecarAccess(RequestEnhancer requestEnhancer,
ResilienceConfig resilienceConfig) {
Set retryCodes = getRetryCodes();
try {
csnEndpoint = ServiceEndpoint.create().destinationName(getDestinationName())
.path(getCsnPath()).returnCodeChecker(getCheckFunction()).retry().forReturnCodes(retryCodes)
.config(resilienceConfig).end();
edmxEndpoint = ServiceEndpoint.create().destinationName(getDestinationName())
.path(getEdmxPath()).returnCodeChecker(getCheckFunction()).retry().forReturnCodes(retryCodes)
.config(resilienceConfig).end();
i18nEndpoint = getI18nPath() != null ? ServiceEndpoint.create().destinationName(getDestinationName())
.path(getI18nPath()).returnCodeChecker(getCheckFunction()).retry().forReturnCodes(retryCodes)
.config(resilienceConfig).end() : null;
} catch (InternalException e) {
throw new CdsCommunicationException(e);
}
this.requestEnhancer = requestEnhancer;
}
private Set getRetryCodes() {
Set retryCodes = new HashSet<>();
retryCodes.add(SC_BAD_GATEWAY);
retryCodes.add(SC_GATEWAY_TIMEOUT);
retryCodes.add(SC_INTERNAL_SERVER_ERROR);
retryCodes.add(SC_SERVICE_UNAVAILABLE);
retryCodes.add(SC_NOT_FOUND);
return retryCodes;
}
protected abstract String getDestinationName();
protected Map getHeaderFields(String eTag) {
Map headerFields = new HashMap<>();
if (!Strings.isNullOrEmpty(eTag)) {
headerFields.put(HttpHeaders.IF_NONE_MATCH, eTag);
}
headerFields.put(HttpHeaders.ACCEPT, APPLICATION_JSON);
return headerFields;
}
private IntFunction getCheckFunction() {
return c -> {
if (c != SC_OK && c != SC_NOT_MODIFIED && c != SC_NO_CONTENT) {
String message = MessageFormat.format("Sidecar returned with status {0}", c);
return new CdsCommunicationException(message, c);
} else {
return null;
}
};
}
/**
* Returns csn model as string, as returned by sidecar
*
* @param id the model identifier
* @param eTag entity tag
* @return the {@link SidecarResponse}
* @throws CdsCommunicationException
*/
public SidecarResponse getCsn(ModelId id, String eTag) throws CdsCommunicationException {
try {
ServiceCall call = createCsnCall(id, eTag);
ServiceResponse response = call.execute(String.class);
return csnSidecarResponse(response, eTag);
} catch (InternalException e) {
throw new CdsCommunicationException(e);
} catch (ServiceException e) {
if (e.getCause() instanceof CdsCommunicationException) {
throw (CdsCommunicationException) e.getCause();
}
throw new CdsCommunicationException(e);
}
}
protected abstract String getCsnPath();
protected abstract ServiceCall createCsnCall(ModelId id, String eTag) throws InternalException;
protected SidecarResponse csnSidecarResponse(ServiceResponse response, String eTag) throws InternalException {
return modelInfo(response, eTag);
}
/**
* Returns edmx model as string, as returned by sidecar
*
* @param id the model identifier
* @param eTag entity tag
* @return the {@link SidecarResponse}
* @throws CdsCommunicationException
*/
public SidecarResponse getEdmx(ModelId id, String eTag) throws CdsCommunicationException {
try {
ServiceCall call = createEdmxCall(id, eTag);
ServiceResponse response = call.execute(String.class);
return edmxSidecarResponse(response, eTag);
} catch (InternalException e) {
throw new CdsCommunicationException(e);
} catch (ServiceException e) {
if (e.getCause() instanceof CdsCommunicationException) {
throw (CdsCommunicationException) e.getCause();
}
throw new CdsCommunicationException(e);
}
}
protected SidecarResponse edmxSidecarResponse(ServiceResponse response, String eTag) throws InternalException {
return modelInfo(response, eTag);
}
private SidecarResponse modelInfo(ServiceResponse response, String eTag) throws InternalException {
if (response.getHttpStatusCode() == SC_NOT_MODIFIED) {
return new SidecarResponse(null, eTag, true);
} else {
String value = response.getPayload().orElse("");
return new SidecarResponse(value, response.getETag().orElse(eTag), false);
}
}
protected abstract String getEdmxPath();
protected abstract ServiceCall createEdmxCall(ModelId id, String eTag) throws InternalException;
/**
* Returns i18n resources as string, as returned by sidecar
*
* @param id the model identifier
* @param eTag entity tag
* @return the {@link SidecarResponse}
* @throws CdsCommunicationException
*/
public SidecarResponse getI18n(ModelId id, String eTag) throws CdsCommunicationException {
try {
ServiceCall call = createI18nCall(id, eTag);
ServiceResponse response = call.execute(String.class);
return i18nSidecarResponse(response, eTag);
} catch (InternalException e) {
throw new CdsCommunicationException(e);
} catch (ServiceException e) {
if (e.getCause() instanceof CdsCommunicationException) {
throw (CdsCommunicationException) e.getCause();
}
throw new CdsCommunicationException(e);
}
}
protected SidecarResponse i18nSidecarResponse(ServiceResponse response, String eTag) throws InternalException {
return modelInfo(response, eTag);
}
protected abstract String getI18nPath();
protected abstract ServiceCall createI18nCall(ModelId id, String eTag) throws InternalException;
}