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.
/*******************************************************************************
* (c) 201X SAP SE or an SAP affiliate company. All rights reserved.
******************************************************************************/
package com.sap.cloud.sdk.odatav2.connectivity.cache.metadata;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.olingo.odata2.api.edm.Edm;
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.ep.EntityProviderException;
import org.apache.olingo.odata2.client.api.ODataClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.sap.cloud.sdk.cloudplatform.cache.CacheKey;
import com.sap.cloud.sdk.cloudplatform.tenant.TenantAccessor;
import com.sap.cloud.sdk.cloudplatform.tenant.TenantFacade;
import com.sap.cloud.sdk.odatav2.connectivity.ErrorResultHandler;
import com.sap.cloud.sdk.odatav2.connectivity.ODataException;
import com.sap.cloud.sdk.odatav2.connectivity.ODataExceptionType;
import com.sap.cloud.sdk.odatav2.connectivity.internal.ODataConnectivityUtil;
public class GuavaMetadataCache implements MetadataCache{
private static Logger logger = LoggerFactory.getLogger(GuavaMetadataCache.class);
private static Cache cache = CacheBuilder.newBuilder().build();
/*
* This method gets the metadata from cache if getMetadataCache boolean is set to true.
* If getMetadataCache is set to false, then it gets fresh metadata even if the metadata is available in cache.
* For both cases,the headers have to be passed.
* This method internally updates the cache if metadata is requested from cache and is not available.
* The updating of the cache is thread safe. If one thread is accessing the cache, the other thread fails with error
* stating "Metadata currently being loaded. Please try again later".
*
*/
public Edm getEdm(final String URL,final HttpClient httpClient,final Map headers, final ErrorResultHandler> errorHandler, Boolean getMetadataFromCache) throws ODataException{
byte[] b=null;
if(getMetadataFromCache){
try {
b = cache.get(URL, new Callable() {
@Override
public byte[] call() throws Exception {
HttpResponse httpResponse = null;
try {
HttpGet httpGet = new HttpGet(URL);
if(headers != null) {
for(Entry e : headers.entrySet()) {
httpGet.addHeader(e.getKey(), e.getValue());
}
}
httpResponse = httpClient.execute(httpGet);
InputStream metadatastream = null;
ODataConnectivityUtil.checkHttpStatus(httpResponse, errorHandler);
metadatastream = httpResponse.getEntity().getContent();
return IOUtils.toByteArray(metadatastream);
//return ODataClient.newInstance().readMetadata(metadatastream, true).getEdm();
} catch (Exception e) {
logger.error("Error occurred during populating metadata : " + e);
throw e;
} finally {
HttpClientUtils.closeQuietly(httpResponse);
}
}
});
InputStream is = new ByteArrayInputStream(b);
return ODataClient.newInstance().readMetadata(is, true).getEdm();
} catch (Exception e) {
logger.error("Error occurred while fetching edm from cache " + e);
throw new ODataException(ODataExceptionType.METADATA_FETCH_FAILED, "Error fetching the metadata", e);
}
}else{
try{
return getEdm(URL, httpClient, headers, errorHandler);
}catch(ODataException e){
logger.error("Error occurred during populating metadata : " + e);
throw e;
}catch(Exception e){
logger.error("Error occurred during populating metadata : " + e);
throw new ODataException(ODataExceptionType.METADATA_FETCH_FAILED, "Error fetching the metadata", e);
}
}
}
/**
* This method gets the metadata from cache if getMetadataCache boolean is set to true.
* If getMetadataCache is set to false, then it gets fresh metadata even if the metadata is available in cache.
* For both cases,the headers have to be passed.
* This method internally updates the cache if metadata is requested from cache and is not available.
* The updating of the cache is thread safe. If one thread is accessing the cache, the other thread fails with error
* stating "Metadata currently being loaded. Please try again later".
*
*/
public Edm getEdm(final String URL,final HttpClient httpClient,final Map headers, final ErrorResultHandler> errorHandler, Boolean getMetadataFromCache,final URL metadataFilePath,CacheKey cacheKey,Boolean isCacheRefresh) throws ODataException{
byte[] b=null;
//If cachekey is null, the defalut tenantIsolation cachekey is generated.
if(cacheKey == null){
cacheKey = getCacheKey(URL);
}
else if(cacheKey != null){
cacheKey.append(URL);
}
//If the isCacheRefresh is true , then remove the entry from the cache.
if(isCacheRefresh){
removeEntry(cacheKey);
}
if(getMetadataFromCache){
try {
b = cache.get(cacheKey.toString(), new Callable() {
@Override
public byte[] call() throws Exception {
return cacheEdm(URL,httpClient,headers,errorHandler,metadataFilePath);
}
});
logger.debug("Fetched the metadata from the cache");
InputStream is = new ByteArrayInputStream(b);
return ODataClient.newInstance().readMetadata(is, true).getEdm();
} catch (Exception e) {
logger.error("Error occurred while fetching edm from cache " , e);
throw new ODataException(ODataExceptionType.METADATA_FETCH_FAILED, "Error fetching the metadata", e);
}
}else{
if(metadataFilePath != null){
try(InputStream metadatastream = metadataFilePath.openStream()){
logger.debug("Fetched the metadata from file.");
return ODataClient.newInstance().readMetadata(metadatastream, true).getEdm();
} catch (IOException | EntityProviderException | EdmException e) {
logger.error("Error occurred while populating metadata : ", e);
throw new ODataException(ODataExceptionType.METADATA_FETCH_FAILED, "Error fetching the metadata", e);
}
}
try{
return getEdm(URL, httpClient, headers, errorHandler);
}catch(ODataException e){
logger.error("Error occurred while populating metadata: " , e);
throw e;
}catch(Exception e){
logger.error("Error occurred while populating metadata : ", e);
throw new ODataException(ODataExceptionType.METADATA_FETCH_FAILED, "Error fetching the metadata", e);
}
}
}
/**
* This method gets the metadata from cache if getMetadataCache boolean is set to true.
* If getMetadataCache is set to false, then it gets fresh metadata even if the metadata is available in cache.
* For both cases,the headers have to be passed.
* This method internally updates the cache if metadata is requested from cache and is not available.
* The updating of the cache is thread safe. If one thread is accessing the cache, the other thread fails with error
* stating "Metadata currently being loaded. Please try again later".
*
*/
public Edm getEdm(final String URL,final HttpClient httpClient,final Map headers, final ErrorResultHandler> errorHandler, Boolean getMetadataFromCache,final URL metadataFilePath) throws ODataException{
return getEdm(URL, httpClient, headers, errorHandler, getMetadataFromCache, metadataFilePath,null,null);
}
private byte[] cacheEdm(final String URL, final HttpClient httpClient, final Map headers,
final ErrorResultHandler> errorHandler, final URL metadataFilePath) throws ODataException {
HttpResponse httpResponse = null;
HttpGet httpGet = new HttpGet(URL);
if (headers != null) {
for (Entry e : headers.entrySet()) {
httpGet.addHeader(e.getKey(), e.getValue());
}
}
// If metadata file present fetch from file else fetch from the service
if (metadataFilePath != null) {
try (InputStream metadatastream = metadataFilePath.openStream()) {
logger.debug("Metadata is not available in the cache. Fetched metadata from file.");
return IOUtils.toByteArray(metadatastream);
} catch (IOException e) {
logger.error("Error occurred while populating metadata : ", e);
throw new ODataException(ODataExceptionType.METADATA_FETCH_FAILED, "Error fetching the metadata", e);
}
} else {
try{
httpResponse = httpClient.execute(httpGet);
ODataConnectivityUtil.checkHttpStatus(httpResponse, errorHandler);
}catch (Exception e) {
logger.error("Error occurred while populating metadata : ", e);
HttpClientUtils.closeQuietly(httpResponse);
throw new ODataException(ODataExceptionType.METADATA_FETCH_FAILED, "Error fetching the metadata", e);
}
try (InputStream metadatastream = httpResponse.getEntity().getContent()) {
logger.debug("Metadata is not available in the cache. Fetched metadata from service.");
return IOUtils.toByteArray(metadatastream);
} catch (IOException e) {
logger.error("Error occurred while populating metadata : ", e);
throw new ODataException(ODataExceptionType.METADATA_FETCH_FAILED, "Error fetching the metadata", e);
} finally {
HttpClientUtils.closeQuietly(httpResponse);
}
}
}
private Edm getEdm(final String URL,final HttpClient httpClient,final Map headers,final ErrorResultHandler> errorHandler) throws ClientProtocolException, IOException, ODataException, EdmException, EntityProviderException{
HttpGet httpGet = new HttpGet(URL);
if(headers != null) {
for(Entry e : headers.entrySet()) {
httpGet.addHeader(e.getKey(), e.getValue());
}
}
HttpResponse httpResponse = null;
httpResponse = httpClient.execute(httpGet);
InputStream metadatastream = null;
ODataConnectivityUtil.checkHttpStatus(httpResponse, errorHandler);
try {
metadatastream = httpResponse.getEntity().getContent();
logger.debug("Fetched metadata from service.");
return ODataClient.newInstance().readMetadata(metadatastream, true).getEdm();
} catch (EntityProviderException e) {
logger.error("Error occurred during populating metadata : " ,e);
throw e;
} finally {
HttpClientUtils.closeQuietly(httpResponse);
}
}
public void removeEntry(String completeUrl) {
cache.invalidate(completeUrl);
}
/**
* Removes the metadata from the cache identified by the cache key.
* @param key {@link com.sap.cloud.sdk.cloudplatform.cache.CacheKey Cache key} representing the metadata cache to be removed
*/
@Override
public void removeEntry(CacheKey cacheKey) {
cache.invalidate(cacheKey);
}
private CacheKey getCacheKey(String metadataUrl) {
CacheKey cacheKey = null;
TenantFacade tenantFacade = TenantAccessor.getTenantFacade();
if (tenantFacade != null && tenantFacade.tryGetCurrentTenant() != null
&& tenantFacade.tryGetCurrentTenant().isSuccess() && tenantFacade.tryGetCurrentTenant().get() != null) {
cacheKey = CacheKey.ofTenantIsolation();
} else {
cacheKey = CacheKey.ofNoIsolation();
}
if(cacheKey != null)
cacheKey.append(metadataUrl);
if (logger.isDebugEnabled()) {
logger.debug("*******CACHE KEY *********** : {} ", cacheKey.toString());
}
return cacheKey;
}
/**
* Clears the cache of all content.
*/
public void clearCache(){
cache.invalidateAll();
}
}