Commit 66e97025 authored by Komal Makkar's avatar Komal Makkar
Browse files

EG changes

parents 5e48b4bc 891c6537
Pipeline #28004 failed with stage
in 8 seconds
......@@ -13,7 +13,7 @@ include:
- project: 'osdu/platform/ci-cd-pipelines'
ref: 'master'
file: 'scanners/fossa.yml'
file: 'scanners/fossa-maven.yml'
- project: 'osdu/platform/ci-cd-pipelines'
ref: 'master'
......
......@@ -18,6 +18,7 @@ The following software have components provided under the terms of this license:
- ASM based accessors helper used by json-smart (from )
- Adapter: RxJava (from )
- Apache Commons Codec (from http://commons.apache.org/proper/commons-codec/)
- Apache Commons Collections (from http://commons.apache.org/proper/commons-collections/)
- Apache Commons Lang (from http://commons.apache.org/proper/commons-lang/)
- Apache Commons Logging (from http://commons.apache.org/proper/commons-logging/)
- Apache HttpAsyncClient (from http://hc.apache.org/httpcomponents-asyncclient)
......@@ -69,6 +70,7 @@ The following software have components provided under the terms of this license:
- Jackson-module-parameter-names (from )
- Java Native Access (from https://github.com/java-native-access/jna)
- Java Native Access Platform (from https://github.com/java-native-access/jna)
- Java UUID Generator (from http://wiki.fasterxml.com/JugHome)
- Javassist (from http://www.javassist.org/)
- Joda-Time (from http://www.joda.org/joda-time/)
- KeePassJava2 :: All (from https://repo1.maven.org/maven2/org/linguafranca/pwdb/KeePassJava2)
......@@ -149,6 +151,7 @@ The following software have components provided under the terms of this license:
- Spring Core (from https://github.com/spring-projects/spring-framework)
- Spring Data Core (from )
- Spring Expression Language (SpEL) (from https://github.com/spring-projects/spring-framework)
- Spring TestContext Framework (from https://github.com/spring-projects/spring-framework)
- Spring Transaction (from https://github.com/spring-projects/spring-framework)
- Spring Web (from https://github.com/spring-projects/spring-framework)
- Spring Web MVC (from https://github.com/spring-projects/spring-framework)
......@@ -332,6 +335,13 @@ The following software have components provided under the terms of this license:
- Project Lombok (from https://projectlombok.org)
- jakarta.annotation-api (from https://projects.eclipse.org/projects/ee4j.ca)
========================================================================
JSON
========================================================================
The following software have components provided under the terms of this license:
- JSON in Java (from https://github.com/douglascrockford/JSON-java)
========================================================================
LGPL-2.1-only
========================================================================
......@@ -369,6 +379,7 @@ MIT
The following software have components provided under the terms of this license:
- Azure Java Client Authentication Library for AutoRest (from https://github.com/Azure/autorest-clientruntime-for-java)
- Azure Java Client Runtime for ARM (from https://github.com/Azure/autorest-clientruntime-for-java)
- Azure Java Client Runtime for AutoRest (from https://github.com/Azure/autorest-clientruntime-for-java)
- Azure Metrics Spring Boot Starter (from https://github.com/Microsoft/azure-spring-boot)
- Azure Spring Boot AutoConfigure (from https://github.com/Microsoft/azure-spring-boot)
......@@ -387,11 +398,13 @@ The following software have components provided under the terms of this license:
- Microsoft Azure Java Core Library (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure Netty HTTP Client Library (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK annotations (from https://github.com/Microsoft/java-api-annotations)
- Microsoft Azure SDK for EventGrid Management (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK for SQL API of Azure Cosmos DB Service (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK for Service Bus (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK for eventgrid (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for Blob Storage (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for Identity (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for KeyVault Keys (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for KeyVault Secrets (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure common module for Storage (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure internal Avro module for Storage (from https://github.com/Azure/azure-sdk-for-java)
......@@ -403,6 +416,8 @@ The following software have components provided under the terms of this license:
- Spongy Castle (from http://rtyley.github.io/spongycastle/)
- Spring Data for Azure Cosmos DB SQL API (from https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/cosmos/azure-spring-data-cosmos)
- adal4j (from https://github.com/AzureAD/azure-activedirectory-library-for-java)
- azure-documentdb (from https://azure.microsoft.com/en-us/services/cosmos-db/)
- documentdb-bulkexecutor (from http://azure.microsoft.com/en-us/services/documentdb/)
- micrometer-core (from https://github.com/micrometer-metrics/micrometer)
- mockito-junit-jupiter (from https://github.com/mockito/mockito)
- msal4j (from https://github.com/AzureAD/microsoft-authentication-library-for-java)
......@@ -464,11 +479,13 @@ The following software have components provided under the terms of this license:
- Joda-Time (from http://www.joda.org/joda-time/)
- LatencyUtils (from http://latencyutils.github.io/LatencyUtils/)
- Microsoft Application Insights Java SDK Core (from https://github.com/Microsoft/ApplicationInsights-Java)
- Microsoft Azure SDK for EventGrid Management (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK for SQL API of Azure Cosmos DB Service (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for Blob Storage (from https://github.com/Azure/azure-sdk-for-java)
- Project Lombok (from https://projectlombok.org)
- Spring Web (from https://github.com/spring-projects/spring-framework)
- StAX API (from http://stax.codehaus.org/)
- azure-documentdb (from https://azure.microsoft.com/en-us/services/cosmos-db/)
- msal4j (from https://github.com/AzureAD/microsoft-authentication-library-for-java)
- reactive-streams (from http://www.reactive-streams.org/)
......
......@@ -20,12 +20,17 @@ import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.models.BlobCopyInfo;
import com.azure.storage.blob.models.BlobErrorCode;
import com.azure.storage.blob.models.BlobStorageException;
import com.azure.storage.blob.models.CopyStatusType;
import com.azure.storage.blob.sas.BlobContainerSasPermission;
import com.azure.storage.blob.sas.BlobSasPermission;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
import com.azure.storage.blob.specialized.BlockBlobClient;
import org.apache.http.HttpStatus;
import org.opengroup.osdu.azure.logging.CoreLoggerFactory;
import org.opengroup.osdu.azure.logging.DependencyPayload;
import org.opengroup.osdu.core.common.logging.ILogger;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.slf4j.helpers.MessageFormatter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
......@@ -34,7 +39,6 @@ import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.OffsetDateTime;
import java.util.Collections;
/**
* A simpler interface to interact with Azure blob storage.
......@@ -78,12 +82,15 @@ import java.util.Collections;
* </pre>
*/
public class BlobStore {
private static final String LOGGER_NAME = BlobStore.class.getName();
private IBlobServiceClientFactory blobServiceClientFactory;
private ILogger logger;
/**
* Constructor to create BlobStore.
* @param factory Factory that provides blob client.
*
* @param factory Factory that provides blob client.
* @param loggerInstance logger instance to be used for logging.
*/
public BlobStore(final IBlobServiceClientFactory factory, final ILogger loggerInstance) {
......@@ -91,8 +98,6 @@ public class BlobStore {
this.logger = loggerInstance;
}
private static final String LOG_PREFIX = "azure-core-lib";
/**
* @param filePath Path of file to be read.
* @param dataPartitionId Data partition id
......@@ -105,19 +110,28 @@ public class BlobStore {
final String containerName) {
BlobContainerClient blobContainerClient = getBlobContainerClient(dataPartitionId, containerName);
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient(filePath).getBlockBlobClient();
final long start = System.currentTimeMillis();
int statusCode = HttpStatus.SC_OK;
try (ByteArrayOutputStream downloadStream = new ByteArrayOutputStream()) {
blockBlobClient.download(downloadStream);
CoreLoggerFactory.getInstance().getLogger(LOGGER_NAME).info("{}", MessageFormatter.format("Done reading from {}", filePath).getMessage());
return downloadStream.toString(StandardCharsets.UTF_8.name());
} catch (BlobStorageException ex) {
statusCode = ex.getStatusCode();
if (ex.getErrorCode().equals(BlobErrorCode.BLOB_NOT_FOUND)) {
throw handleBlobStoreException(404, "Specified blob was not found", ex);
}
throw handleBlobStoreException(500, "Failed to read specified blob", ex);
} catch (UnsupportedEncodingException ex) {
throw handleBlobStoreException(400, String.format("Encoding was not correct for item with name=%s", filePath), ex);
statusCode = HttpStatus.SC_BAD_REQUEST;
throw handleBlobStoreException(400, MessageFormatter.format("Encoding was not correct for item with name={}", filePath).getMessage(), ex);
} catch (IOException ex) {
throw handleBlobStoreException(500, String.format("Malformed document for item with name=%s", filePath), ex);
statusCode = HttpStatus.SC_INTERNAL_SERVER_ERROR;
throw handleBlobStoreException(500, MessageFormatter.format("Malformed document for item with name={}", filePath).getMessage(), ex);
} finally {
final long timeTaken = System.currentTimeMillis() - start;
final String dependencyData = MessageFormatter.arrayFormat("{}:{}/{}", new String[]{dataPartitionId, containerName, filePath}).getMessage();
logDependency("READ_FROM_STORAGE_CONTAINER", dependencyData, dependencyData, timeTaken, String.valueOf(statusCode), statusCode == HttpStatus.SC_OK);
}
}
......@@ -133,14 +147,22 @@ public class BlobStore {
final String containerName) {
BlobContainerClient blobContainerClient = getBlobContainerClient(dataPartitionId, containerName);
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient(filePath).getBlockBlobClient();
final long start = System.currentTimeMillis();
int statusCode = HttpStatus.SC_OK;
try {
blockBlobClient.delete();
CoreLoggerFactory.getInstance().getLogger(LOGGER_NAME).info("{}", MessageFormatter.format("Done deleting blob at {}", filePath).getMessage());
return true;
} catch (BlobStorageException ex) {
statusCode = ex.getStatusCode();
if (ex.getErrorCode().equals(BlobErrorCode.BLOB_NOT_FOUND)) {
throw handleBlobStoreException(404, "Specified blob was not found", ex);
}
throw handleBlobStoreException(500, "Failed to delete blob", ex);
} finally {
final long timeTaken = System.currentTimeMillis() - start;
final String dependencyData = MessageFormatter.arrayFormat("{}:{}/{}", new String[]{dataPartitionId, containerName, filePath}).getMessage();
logDependency("DELETE_FROM_STORAGE_CONTAINER", dependencyData, dependencyData, timeTaken, String.valueOf(statusCode), statusCode == HttpStatus.SC_OK);
}
}
......@@ -159,12 +181,22 @@ public class BlobStore {
int bytesSize = bytes.length;
BlobContainerClient blobContainerClient = getBlobContainerClient(dataPartitionId, containerName);
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient(filePath).getBlockBlobClient();
final long start = System.currentTimeMillis();
int statusCode = HttpStatus.SC_OK;
try (ByteArrayInputStream dataStream = new ByteArrayInputStream(bytes)) {
blockBlobClient.upload(dataStream, bytesSize, true);
CoreLoggerFactory.getInstance().getLogger(LOGGER_NAME).info("{}", MessageFormatter.format("Done uploading file content to %s", filePath).getMessage());
} catch (BlobStorageException ex) {
statusCode = ex.getStatusCode();
throw handleBlobStoreException(500, "Failed to upload file content.", ex);
} catch (IOException ex) {
throw handleBlobStoreException(500, String.format("Malformed document for item with name=%s", filePath), ex);
statusCode = HttpStatus.SC_INTERNAL_SERVER_ERROR;
throw handleBlobStoreException(500, MessageFormatter.format("Malformed document for item with name={}", filePath).getMessage(), ex);
} finally {
final long timeTaken = System.currentTimeMillis() - start;
final String dependencyData = MessageFormatter.format("{}:{}/{}", new String[]{dataPartitionId, containerName, filePath}).getMessage();
logDependency("WRITE_TO_STORAGE_CONTAINER", dependencyData, dependencyData, timeTaken, String.valueOf(statusCode), statusCode == HttpStatus.SC_OK);
}
}
......@@ -198,10 +230,11 @@ public class BlobStore {
/**
* Generates pre-signed url to a blob container.
*
* @param dataPartitionId data partition id
* @param containerName Name of the storage container
* @param expiryTime Time after which the token expires
* @param permissions permissions for the given container
* @param containerName Name of the storage container
* @param expiryTime Time after which the token expires
* @param permissions permissions for the given container
* @return Generates pre-signed url for a given container
*/
public String generatePreSignedURL(final String dataPartitionId, final String containerName, final OffsetDateTime expiryTime, final BlobContainerSasPermission permissions) {
......@@ -211,6 +244,7 @@ public class BlobStore {
/**
* Method is used to copy a file specified at Source URL to the provided destination.
*
* @param dataPartitionId Data partition id
* @param filePath Path of file (blob) to which the file has to be copied
* @param containerName Name of the storage container
......@@ -218,34 +252,49 @@ public class BlobStore {
* @return Blob Copy Final Result.
*/
public BlobCopyInfo copyFile(final String dataPartitionId, final String filePath, final String containerName,
final String sourceUrl) {
final String sourceUrl) {
BlobContainerClient blobContainerClient = getBlobContainerClient(dataPartitionId, containerName);
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient(filePath).getBlockBlobClient();
final long start = System.currentTimeMillis();
SyncPoller<BlobCopyInfo, Void> result = blockBlobClient.beginCopy(sourceUrl, Duration.ofSeconds(1));
return result.waitForCompletion().getValue();
BlobCopyInfo blobCopyInfo = result.waitForCompletion().getValue();
final long timeTaken = System.currentTimeMillis() - start;
final String target = MessageFormatter.arrayFormat("{}:{}/{}", new String[]{dataPartitionId, containerName, filePath}).getMessage();
CopyStatusType status = blobCopyInfo == null ? CopyStatusType.FAILED : blobCopyInfo.getCopyStatus();
logDependency("COPY_FILE", sourceUrl, target, timeTaken, status.toString(), status == CopyStatusType.SUCCESS);
return blobCopyInfo;
}
/**
*
* @param blockBlobClient Blob client
* @param expiryTime Time after which SAS Token expires
* @param permissions Permissions for the given blob
* @param expiryTime Time after which SAS Token expires
* @param permissions Permissions for the given blob
* @return Generates SAS Token.
*/
private String generateSASToken(final BlockBlobClient blockBlobClient, final OffsetDateTime expiryTime, final BlobSasPermission permissions) {
BlobServiceSasSignatureValues blobServiceSasSignatureValues = new BlobServiceSasSignatureValues(expiryTime, permissions);
return blockBlobClient.generateSas(blobServiceSasSignatureValues);
final long start = System.currentTimeMillis();
String sasToken = blockBlobClient.generateSas(blobServiceSasSignatureValues);
final long timeTaken = System.currentTimeMillis() - start;
logDependency("GENERATE_SAS_TOKEN", blockBlobClient.getBlobName(), blockBlobClient.getBlobUrl(), timeTaken, String.valueOf(HttpStatus.SC_OK), true);
return sasToken;
}
/**
* @param client Container client
* @param expiryTime Time after which SAS Token expires
* @param client Container client
* @param expiryTime Time after which SAS Token expires
* @param permissions Permissions for the given container
* @return Generates SAS Token.
*/
private String generateSASToken(final BlobContainerClient client, final OffsetDateTime expiryTime, final BlobContainerSasPermission permissions) {
BlobServiceSasSignatureValues blobServiceSasSignatureValues = new BlobServiceSasSignatureValues(expiryTime, permissions);
return client.generateSas(blobServiceSasSignatureValues);
final long start = System.currentTimeMillis();
String sasToken = client.generateSas(blobServiceSasSignatureValues);
final long timeTaken = System.currentTimeMillis() - start;
logDependency("GENERATE_SAS_TOKEN", client.getBlobContainerName(), client.getBlobContainerUrl(), timeTaken, String.valueOf(HttpStatus.SC_OK), true);
return sasToken;
}
/**
......@@ -273,7 +322,25 @@ public class BlobStore {
* @return Instance of AppException
*/
private AppException handleBlobStoreException(final int status, final String errorMessage, final Exception ex) {
logger.warning(LOG_PREFIX, errorMessage, Collections.<String, String>emptyMap());
CoreLoggerFactory.getInstance().getLogger(LOGGER_NAME).warn(MessageFormatter.format("{}", errorMessage).getMessage(), ex);
return new AppException(status, errorMessage, ex.getMessage(), ex);
}
/**
* Log dependency.
*
* @param name the name of the command initiated with this dependency call
* @param data the command initiated by this dependency call
* @param target the target of this dependency call
* @param timeTakenInMs the request duration in milliseconds
* @param resultCode the result code of the call
* @param success indication of successful or unsuccessful call
*/
private void logDependency(final String name, final String data, final String target, final long timeTakenInMs, final String resultCode, final boolean success) {
DependencyPayload payload = new DependencyPayload(name, data, Duration.ofMillis(timeTakenInMs), resultCode, success);
payload.setType("BlobStore");
payload.setTarget(target);
CoreLoggerFactory.getInstance().getLogger(LOGGER_NAME).logDependency(payload);
}
}
package org.opengroup.osdu.azure.cache;
import com.microsoft.azure.documentdb.bulkexecutor.DocumentBulkExecutor;
import org.opengroup.osdu.core.common.cache.VmCache;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* Implementation of ICache for DocumentBulkExecutor.
*/
@Component
@Lazy
public class CosmosBulkExecutorCache extends VmCache<String, DocumentBulkExecutor> {
/**
* Default cache constructor.
*/
public CosmosBulkExecutorCache() {
super(60 * 60, 1000);
}
/**
* @param key cache key
* @return true if found in cache
*/
public boolean containsKey(final String key) {
return this.get(key) != null;
}
}
\ No newline at end of file
package org.opengroup.osdu.azure.cache;
import org.opengroup.osdu.core.common.cache.VmCache;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import com.azure.security.keyvault.keys.cryptography.CryptographyClient;
/**
* Implementation of ICache for CryptographyClient.
*/
@Lazy
@Component
public class CryptographyClientCache extends VmCache<String, CryptographyClient> {
/**
* Default cache constructor.
*/
public CryptographyClientCache() {
super(60 * 60, 1000);
}
/**
* @param key cache key
* @return true if found in cache
*/
public boolean containsKey(final String key) {
return this.get(key) != null;
}
}
package org.opengroup.osdu.azure.cache;
import org.opengroup.osdu.core.common.cache.VmCache;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import com.microsoft.azure.management.eventgrid.v2020_04_01_preview.implementation.EventGridManager;
/**
* Implementation of ICache for CryptographyClient.
*/
@Lazy
@Component
public class EventGridManagerCache extends VmCache<String, EventGridManager> {
/**
* Default cache constructor.
*/
public EventGridManagerCache() {
super(60 * 60, 1000);
}
/**
* @param key cache key
* @return true if found in cache
*/
public boolean containsKey(final String key) {
return this.get(key) != null;
}
}
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.azure.concurrency;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/***
* Custom Executors class that returns a custom thread pool executor {@link CustomThreadPoolExecutor}.
*/
public final class CustomExecutors {
/***
* Private constructor -- this class should never be instantiated.
*/
private CustomExecutors() {
}
/***
* Returning new custom thread pool executor.
* @param nThreads corresponding to corePoolSize and maxPoolSize.
* @return instance of {@link CustomThreadPoolExecutor}
*/
public static ExecutorService newFixedThreadPool(final int nThreads) {
return new CustomThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
}
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.azure.concurrency;
import org.springframework.web.context.request.RequestContextHolder;
import javax.validation.constraints.NotNull;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/***
* A custom thread pool executor that executes code in the new thread after copying the MDC and request context.
*/
public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
/***
* Calling constructor of the super class.
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
*/
public CustomThreadPoolExecutor(
final int corePoolSize,
final int maximumPoolSize,
final long keepAliveTime,
final TimeUnit unit,
final BlockingQueue<Runnable> workQueue
) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
/**
* Calling execute method of super class after wrapping the executable code with MDC and thread context.
* @param command
*/
@Override
public void execute(final @NotNull Runnable command) {
super.execute(CustomThreadPoolExecutorUtil.wrapWithContext(command, RequestContextHolder.currentRequestAttributes()));
}
}
package org.opengroup.osdu.azure.concurrency;
import org.jetbrains.annotations.NotNull;
import org.opengroup.osdu.azure.logging.CoreLoggerFactory;
import org.slf4j.MDC;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import java.util.Map;
/***
* Utils class for CustomThreadPoolExecutor {@link CustomThreadPoolExecutor}.
*/
public final class CustomThreadPoolExecutorUtil {
private static final String LOGGER_NAME = CustomThreadPoolExecutorUtil.class.getName();
/***
* Constructor marked as private so that this class is never instantiated.
*/
private CustomThreadPoolExecutorUtil() {
}
/***
* Copy the MDC and request context to the Runnable object being returned.
* @param task instance of Runnable class.
* @param context the RequestAttributes to be copied to new thread.
* @return Runnable instance wrapped with request context and MDC.
*/
public static Runnable wrapWithContext(final @NotNull Runnable task, final RequestAttributes context) {
Map<String, String> contextMap = MDC.getCopyOfContextMap();
return () -> {
//save the current MDC context
setMDCContext(contextMap);
//save the current request attributes
setRequestContext(context);
try {
task.run();
} finally {
// once the task is complete, clear MDC
MDC.clear();
RequestContextHolder.resetRequestAttributes();
}
};
}
/***
* Set the MDC.
* @param contextMap the MDC map to be copied.
*/
private static void setMDCContext(final Map<String, String> contextMap) {
MDC.clear();
if (contextMap != null) {
MDC.setContextMap(contextMap);
} else {
CoreLoggerFactory.getInstance().getLogger(LOGGER_NAME).warn("Cannot set MDC as it is null");
}
}
/***
* Set the Request Attributes.