From 4c199ed39f072a2a6d147febb206073848deb1b8 Mon Sep 17 00:00:00 2001 From: sowmya-dixit Date: Mon, 19 Feb 2024 18:16:41 +0530 Subject: [PATCH 1/4] fix: S3 data fetcher fixes to connect with AWS --- .../org/ekstep/analytics/framework/fetcher/S3DataFetcher.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/S3DataFetcher.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/S3DataFetcher.scala index 51db71e..d132edf 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/S3DataFetcher.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/S3DataFetcher.scala @@ -36,7 +36,7 @@ object S3DataFetcher { } private def getKeys(query: Query)(implicit fc: FrameworkContext) : Array[String] = { - val storageService = fc.getStorageService("aws"); + val storageService = fc.getStorageService("aws", "aws_storage_key", "aws_storage_secret"); val keys = storageService.searchObjects(getBucket(query.bucket), getPrefix(query.prefix), query.startDate, query.endDate, query.delta, query.datePattern.getOrElse("yyyy-MM-dd")) storageService.getPaths(getBucket(query.bucket), keys).toArray } From 8d263e17cc2546a4d533d1906f5c47eea44ac3d2 Mon Sep 17 00:00:00 2001 From: sowmya-dixit Date: Wed, 21 Feb 2024 12:46:55 +0530 Subject: [PATCH 2/4] #OB-553 fix: Analytics Core issue fixes for OCI --- .../lib/cloud-store-sdk_2.12-1.4.6.jar | Bin 0 -> 97087 bytes analytics-core/pom.xml | 39 ++++++++++++++++-- .../framework/fetcher/AzureDataFetcher.scala | 2 +- .../framework/fetcher/CephS3DataFetcher.scala | 2 +- .../framework/fetcher/OCIDataFetcher.scala | 2 +- .../framework/fetcher/S3DataFetcher.scala | 2 +- .../storage/CustomOCIStorageService.scala | 2 +- .../storage/CustomS3StorageService.scala | 2 +- .../analytics/framework/util/CSPUtils.scala | 26 ++++++------ .../analytics/framework/util/CommonUtil.scala | 16 +++---- .../framework/util/DatasetUtil.scala | 4 +- .../analytics/framework/TestDataFetcher.scala | 2 +- .../framework/util/TestCommonUtil.scala | 6 +-- 13 files changed, 69 insertions(+), 36 deletions(-) create mode 100644 analytics-core/lib/cloud-store-sdk_2.12-1.4.6.jar diff --git a/analytics-core/lib/cloud-store-sdk_2.12-1.4.6.jar b/analytics-core/lib/cloud-store-sdk_2.12-1.4.6.jar new file mode 100644 index 0000000000000000000000000000000000000000..725eedf850950f717d014dc9c8d929d484f0f88a GIT binary patch literal 97087 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 z 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 literal 0 HcmV?d00001 diff --git a/analytics-core/pom.xml b/analytics-core/pom.xml index fdcca52..716c85f 100644 --- a/analytics-core/pom.xml +++ b/analytics-core/pom.xml @@ -216,9 +216,17 @@ --> - ${CLOUD_STORE_GROUP_ID} - ${CLOUD_STORE_ARTIFACT_ID} - ${CLOUD_STORE_VERSION} + + + + + + + org.sunbird + cloud-store-sdk_2.12 + 1.4.6 + system + ${project.basedir}/lib/cloud-store-sdk_2.12-1.4.6.jar com.microsoft.azure @@ -242,6 +250,31 @@ + + org.apache.jclouds + jclouds-all + 2.2.1 + + + com.jamesmurty.utils + java-xmlbuilder + + + org.yaml + snakeyaml + + + + + org.apache.tika + tika-core + 1.18 + + + org.apache.hadoop + hadoop-azure + 2.7.3 + com.microsoft.azure azure-storage diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/AzureDataFetcher.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/AzureDataFetcher.scala index d46a49d..307bd64 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/AzureDataFetcher.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/AzureDataFetcher.scala @@ -14,7 +14,7 @@ object AzureDataFetcher { val keys = for(query <- queries) yield { val paths = if(query.folder.isDefined && query.endDate.isDefined && query.folder.getOrElse("false").equals("true")) { - Array("wasb://"+getBucket(query.bucket) + "@" + AppConf.getStorageKey("azure") + ".blob.core.windows.net" + "/" + getPrefix(query.prefix) + query.endDate.getOrElse("")) + Array("wasb://"+getBucket(query.bucket) + "@" + AppConf.getStorageKey + ".blob.core.windows.net" + "/" + getPrefix(query.prefix) + query.endDate.getOrElse("")) } else { getKeys(query); } diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/CephS3DataFetcher.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/CephS3DataFetcher.scala index 190f3f3..dc77dc2 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/CephS3DataFetcher.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/CephS3DataFetcher.scala @@ -16,7 +16,7 @@ object CephS3DataFetcher { val keys = for(query <- queries) yield { val paths = if(query.folder.isDefined && query.endDate.isDefined && query.folder.getOrElse("false").equals("true")) { - Array("s3n://" + getBucket(query.bucket) + "/" + getPrefix(query.prefix) + query.endDate.get) + Array("s3a://" + getBucket(query.bucket) + "/" + getPrefix(query.prefix) + query.endDate.get) } else { getKeys(query); } diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/OCIDataFetcher.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/OCIDataFetcher.scala index 9133534..a42218a 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/OCIDataFetcher.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/OCIDataFetcher.scala @@ -14,7 +14,7 @@ object OCIDataFetcher { val keys = for(query <- queries) yield { val paths = if(query.folder.isDefined && query.endDate.isDefined && query.folder.getOrElse("false").equals("true")) { - Array("s3n://" + getBucket(query.bucket) + "/" + getPrefix(query.prefix) + query.endDate.get) + Array("s3a://" + getBucket(query.bucket) + "/" + getPrefix(query.prefix) + query.endDate.get) } else { getKeys(query); } diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/S3DataFetcher.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/S3DataFetcher.scala index d132edf..acacdb4 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/S3DataFetcher.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/fetcher/S3DataFetcher.scala @@ -21,7 +21,7 @@ object S3DataFetcher { val keys = for(query <- queries) yield { val paths = if(query.folder.isDefined && query.endDate.isDefined && query.folder.getOrElse("false").equals("true")) { - Array("s3n://"+getBucket(query.bucket)+"/"+getPrefix(query.prefix) + query.endDate.get) + Array("s3a://"+getBucket(query.bucket)+"/"+getPrefix(query.prefix) + query.endDate.get) } else { getKeys(query); } diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/storage/CustomOCIStorageService.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/storage/CustomOCIStorageService.scala index a306197..c14a970 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/storage/CustomOCIStorageService.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/storage/CustomOCIStorageService.scala @@ -27,6 +27,6 @@ class CustomOCIStorageService(config: StorageConfig) extends BaseStorageService var blobStore: BlobStore = context.getBlobStore override def getPaths(container: String, objects: List[Blob]): List[String] = { - objects.map{f => "s3n://" + container + "/" + f.key} + objects.map{f => "s3a://" + container + "/" + f.key} } } \ No newline at end of file diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/storage/CustomS3StorageService.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/storage/CustomS3StorageService.scala index 976baaf..95a358d 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/storage/CustomS3StorageService.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/storage/CustomS3StorageService.scala @@ -12,6 +12,6 @@ class CustomS3StorageService(config: StorageConfig) extends BaseStorageService { var blobStore: BlobStore = context.getBlobStore override def getPaths(container: String, objects: List[Blob]): List[String] = { - objects.map{f => "s3n://" + container + "/" + f.key} + objects.map{f => "s3a://" + container + "/" + f.key} } } \ No newline at end of file diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CSPUtils.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CSPUtils.scala index a0d1736..7a692ec 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CSPUtils.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CSPUtils.scala @@ -21,13 +21,13 @@ object S3Provider extends ICloudStorageProvider { implicit val className: String = "org.ekstep.analytics.framework.util.S3Provider" override def setConf(sc: SparkContext, storageKey: Option[String], storageSecret: Option[String]): Unit = { JobLogger.log("Configuring S3 Access Key & Secret Key to SparkContext") - val key = storageKey.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getAwsKey()) - val secret = storageSecret.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getAwsSecret()) - sc.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", key) - sc.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey", secret) + val key = storageKey.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageKey) + val secret = storageSecret.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageSecret) + sc.hadoopConfiguration.set("fs.s3a.awsAccessKeyId", key) + sc.hadoopConfiguration.set("fs.s3a.awsSecretAccessKey", secret) val storageEndpoint = AppConf.getConfig("cloud_storage_endpoint") if (storageEndpoint.nonEmpty) { - sc.hadoopConfiguration.set("fs.s3n.endpoint", storageEndpoint) + sc.hadoopConfiguration.set("fs.s3a.endpoint", storageEndpoint) } } } @@ -36,8 +36,8 @@ object AzureProvider extends ICloudStorageProvider { implicit val className: String = "org.ekstep.analytics.framework.util.AzureProvider" override def setConf(sc: SparkContext, storageKey: Option[String], storageSecret: Option[String]): Unit = { JobLogger.log("Configuring Azure Access Key & Secret Key to SparkContext") - val key = storageKey.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageKey("azure")) - val secret = storageSecret.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageSecret("azure")) + val key = storageKey.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageKey) + val secret = storageSecret.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageSecret) sc.hadoopConfiguration.set("fs.azure", "org.apache.hadoop.fs.azure.NativeAzureFileSystem") sc.hadoopConfiguration.set("fs.azure.account.key." + key + ".blob.core.windows.net", secret) sc.hadoopConfiguration.set("fs.azure.account.keyprovider." + key + ".blob.core.windows.net", "org.apache.hadoop.fs.azure.SimpleKeyProvider") @@ -47,8 +47,8 @@ object GcpProvider extends ICloudStorageProvider { implicit val className: String = "org.ekstep.analytics.framework.util.GcpProvider" override def setConf(sc: SparkContext, storageKey: Option[String], storageSecret: Option[String]): Unit = { JobLogger.log("Configuring GCP Access Key & Secret Key to SparkContext") - val key = storageKey.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageKey("gcloud")) - val secret = storageSecret.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageSecret("gcloud")) + val key = storageKey.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageKey) + val secret = storageSecret.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageSecret) sc.hadoopConfiguration.set("fs.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem") sc.hadoopConfiguration.set("fs.AbstractFileSystem.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS") sc.hadoopConfiguration.set("fs.gs.auth.service.account.email", key) @@ -60,10 +60,10 @@ object GcpProvider extends ICloudStorageProvider { object OCIProvider extends ICloudStorageProvider { implicit val className: String = "org.ekstep.analytics.framework.util.OCIProvider" override def setConf(sc: SparkContext, storageKey: Option[String], storageSecret: Option[String]): Unit = { - val key = storageKey.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageKey("oci")) - val secret = storageSecret.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageSecret("oci")) + val key = storageKey.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageKey) + val secret = storageSecret.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageSecret) JobLogger.log("Configuring OCI Access Key & Secret Key to SparkContext") - sc.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", key); - sc.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey", secret); + sc.hadoopConfiguration.set("fs.s3a.awsAccessKeyId", key); + sc.hadoopConfiguration.set("fs.s3a.awsSecretAccessKey", secret); } } \ No newline at end of file diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CommonUtil.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CommonUtil.scala index 2e02a07..cc48b82 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CommonUtil.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CommonUtil.scala @@ -700,7 +700,7 @@ object CommonUtil { } def getS3File(bucket: String, file: String): String = { - "s3n://" + bucket + "/" + file; + "s3a://" + bucket + "/" + file; } def getS3FileWithoutPrefix(bucket: String, file: String): String = { @@ -726,21 +726,21 @@ object CommonUtil { def setStorageConf(store: String, accountKey: Option[String], accountSecret: Option[String])(implicit sc: SparkContext): Configuration = { store.toLowerCase() match { case "s3" => - sc.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", AppConf.getConfig(accountKey.getOrElse("aws_storage_key"))); - sc.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey", AppConf.getConfig(accountSecret.getOrElse("aws_storage_secret"))); + sc.hadoopConfiguration.set("fs.s3a.awsAccessKeyId", AppConf.getConfig(accountKey.getOrElse("aws_storage_key"))); + sc.hadoopConfiguration.set("fs.s3a.awsSecretAccessKey", AppConf.getConfig(accountSecret.getOrElse("aws_storage_secret"))); case "azure" => sc.hadoopConfiguration.set("fs.azure", "org.apache.hadoop.fs.azure.NativeAzureFileSystem") sc.hadoopConfiguration.set("fs.azure.account.key." + AppConf.getConfig(accountKey.getOrElse("azure_storage_key")) + ".blob.core.windows.net", AppConf.getConfig(accountSecret.getOrElse("azure_storage_secret"))) case "gcloud" => sc.hadoopConfiguration.set("fs.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem") sc.hadoopConfiguration.set("fs.AbstractFileSystem.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS") - sc.hadoopConfiguration.set("fs.gs.auth.service.account.email", AppConf.getStorageKey("gcloud")) - sc.hadoopConfiguration.set("fs.gs.auth.service.account.private.key", AppConf.getStorageSecret("gcloud")) + sc.hadoopConfiguration.set("fs.gs.auth.service.account.email", AppConf.getStorageKey) + sc.hadoopConfiguration.set("fs.gs.auth.service.account.private.key", AppConf.getStorageSecret) sc.hadoopConfiguration.set("fs.gs.auth.service.account.private.key.id", AppConf.getConfig("gcloud_private_secret_id")) case "oci" => - sc.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", AppConf.getConfig(accountKey.getOrElse("aws_storage_key"))); - sc.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey", AppConf.getConfig(accountSecret.getOrElse("aws_storage_secret"))); - // sc.hadoopConfiguration.set("fs.s3n.endpoint", AppConf.getConfig(accountSecret.getOrElse("cloud_storage_endpoint_with_protocol"))); + sc.hadoopConfiguration.set("fs.s3a.awsAccessKeyId", AppConf.getConfig(accountKey.getOrElse("aws_storage_key"))); + sc.hadoopConfiguration.set("fs.s3a.awsSecretAccessKey", AppConf.getConfig(accountSecret.getOrElse("aws_storage_secret"))); + // sc.hadoopConfiguration.set("fs.s3a.endpoint", AppConf.getConfig(accountSecret.getOrElse("cloud_storage_endpoint_with_protocol"))); case _ => // Do nothing } diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/DatasetUtil.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/DatasetUtil.scala index c6646e3..8aa8c83 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/DatasetUtil.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/DatasetUtil.scala @@ -57,13 +57,13 @@ class DatasetExt(df: Dataset[Row]) { val filePrefix = storageConfig.store.toLowerCase() match { case "s3" => - "s3n://" + "s3a://" case "azure" => "wasb://" case "gcloud" => "gs://" case "oci" => - "s3n://" + "s3a://" case _ => "" } diff --git a/analytics-core/src/test/scala/org/ekstep/analytics/framework/TestDataFetcher.scala b/analytics-core/src/test/scala/org/ekstep/analytics/framework/TestDataFetcher.scala index c7974d8..c56d4c2 100644 --- a/analytics-core/src/test/scala/org/ekstep/analytics/framework/TestDataFetcher.scala +++ b/analytics-core/src/test/scala/org/ekstep/analytics/framework/TestDataFetcher.scala @@ -119,7 +119,7 @@ class TestDataFetcher extends SparkSpec with Matchers with MockFactory { it should "cover the missing branches in S3DataFetcher, AzureDataFetcher and DruidDataFetcher" in { implicit val fc = new FrameworkContext(); var query = JSONUtils.deserialize[Query]("""{"bucket":"test-container","prefix":"test/","folder":"true","endDate":"2020-01-10"}""") - S3DataFetcher.getObjectKeys(Array(query)).head should be ("s3n://test-container/test/2020-01-10") + S3DataFetcher.getObjectKeys(Array(query)).head should be ("s3a://test-container/test/2020-01-10") AzureDataFetcher.getObjectKeys(Array(query)).head should be ("wasb://test-container@azure-test-key.blob.core.windows.net/test/2020-01-10") query = JSONUtils.deserialize[Query]("""{"bucket":"test-container","prefix":"test/","folder":"true","endDate":"2020-01-10","excludePrefix":"test"}""") diff --git a/analytics-core/src/test/scala/org/ekstep/analytics/framework/util/TestCommonUtil.scala b/analytics-core/src/test/scala/org/ekstep/analytics/framework/util/TestCommonUtil.scala index ef89e47..267ef37 100644 --- a/analytics-core/src/test/scala/org/ekstep/analytics/framework/util/TestCommonUtil.scala +++ b/analytics-core/src/test/scala/org/ekstep/analytics/framework/util/TestCommonUtil.scala @@ -317,8 +317,8 @@ class TestCommonUtil extends BaseSpec { azureStorageConf.get("fs.azure.account.key.azure-test-key.blob.core.windows.net") should be("azure-test-secret") val s3StorageConf = CommonUtil.setStorageConf("s3", Option("aws_storage_key"), Option("aws_storage_secret")) - s3StorageConf.get("fs.s3n.awsAccessKeyId") should be("aws-test-key") - s3StorageConf.get("fs.s3n.awsSecretAccessKey") should be("aws-test-secret") + s3StorageConf.get("fs.s3a.awsAccessKeyId") should be("aws-test-key") + s3StorageConf.get("fs.s3a.awsSecretAccessKey") should be("aws-test-secret") val fileUtil = new HadoopFileUtil; val copiedFile = fileUtil.copy("src/test/resources/sample_telemetry.log", "src/test/resources/sample_telemetry.json", sc.hadoopConfiguration) @@ -332,7 +332,7 @@ class TestCommonUtil extends BaseSpec { azureUrl should be ("wasb://telemetry-data-store@azure-test-key.blob.core.windows.net/report/archival-data/batch-001/2021-21-*.csv.gz") val s3Url = CommonUtil.getBlobUrl("s3", "report/archival-data/batch-001/2021-21-*.csv.gz", "telemetry-data-store") - s3Url should be ("s3n://telemetry-data-store/report/archival-data/batch-001/2021-21-*.csv.gz") + s3Url should be ("s3a://telemetry-data-store/report/archival-data/batch-001/2021-21-*.csv.gz") sc.stop() } From 0888c20fe3101737cf5e2cfb040267823ff6f541 Mon Sep 17 00:00:00 2001 From: sowmya-dixit Date: Mon, 26 Feb 2024 17:23:19 +0530 Subject: [PATCH 3/4] #OB-553 fix: Analytics Framework issue fixes for OCI --- .../ekstep/analytics/framework/util/CSPUtils.scala | 13 +++++++++---- .../analytics/framework/util/CommonUtil.scala | 10 +++++----- .../analytics/framework/util/TestCommonUtil.scala | 4 ++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CSPUtils.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CSPUtils.scala index 7a692ec..9552a23 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CSPUtils.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CSPUtils.scala @@ -23,8 +23,8 @@ object S3Provider extends ICloudStorageProvider { JobLogger.log("Configuring S3 Access Key & Secret Key to SparkContext") val key = storageKey.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageKey) val secret = storageSecret.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageSecret) - sc.hadoopConfiguration.set("fs.s3a.awsAccessKeyId", key) - sc.hadoopConfiguration.set("fs.s3a.awsSecretAccessKey", secret) + sc.hadoopConfiguration.set("fs.s3a.access.key", key) + sc.hadoopConfiguration.set("fs.s3a.secret.key", secret) val storageEndpoint = AppConf.getConfig("cloud_storage_endpoint") if (storageEndpoint.nonEmpty) { sc.hadoopConfiguration.set("fs.s3a.endpoint", storageEndpoint) @@ -63,7 +63,12 @@ object OCIProvider extends ICloudStorageProvider { val key = storageKey.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageKey) val secret = storageSecret.filter(_.nonEmpty).map(value => AppConf.getConfig(value)).getOrElse(AppConf.getStorageSecret) JobLogger.log("Configuring OCI Access Key & Secret Key to SparkContext") - sc.hadoopConfiguration.set("fs.s3a.awsAccessKeyId", key); - sc.hadoopConfiguration.set("fs.s3a.awsSecretAccessKey", secret); + sc.hadoopConfiguration.set("fs.s3a.access.key", key); + sc.hadoopConfiguration.set("fs.s3a.secret.key", secret); + sc.hadoopConfiguration.set("fs.s3a.path.style.access", "true") + val storageEndpoint = AppConf.getConfig("cloud_storage_endpoint_with_protocol") + if (storageEndpoint.nonEmpty) { + sc.hadoopConfiguration.set("fs.s3a.endpoint", storageEndpoint) + } } } \ No newline at end of file diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CommonUtil.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CommonUtil.scala index cc48b82..1c998d9 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CommonUtil.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/CommonUtil.scala @@ -726,8 +726,8 @@ object CommonUtil { def setStorageConf(store: String, accountKey: Option[String], accountSecret: Option[String])(implicit sc: SparkContext): Configuration = { store.toLowerCase() match { case "s3" => - sc.hadoopConfiguration.set("fs.s3a.awsAccessKeyId", AppConf.getConfig(accountKey.getOrElse("aws_storage_key"))); - sc.hadoopConfiguration.set("fs.s3a.awsSecretAccessKey", AppConf.getConfig(accountSecret.getOrElse("aws_storage_secret"))); + sc.hadoopConfiguration.set("fs.s3a.access.key", AppConf.getConfig(accountKey.getOrElse("aws_storage_key"))); + sc.hadoopConfiguration.set("fs.s3a.secret.key", AppConf.getConfig(accountSecret.getOrElse("aws_storage_secret"))); case "azure" => sc.hadoopConfiguration.set("fs.azure", "org.apache.hadoop.fs.azure.NativeAzureFileSystem") sc.hadoopConfiguration.set("fs.azure.account.key." + AppConf.getConfig(accountKey.getOrElse("azure_storage_key")) + ".blob.core.windows.net", AppConf.getConfig(accountSecret.getOrElse("azure_storage_secret"))) @@ -738,9 +738,9 @@ object CommonUtil { sc.hadoopConfiguration.set("fs.gs.auth.service.account.private.key", AppConf.getStorageSecret) sc.hadoopConfiguration.set("fs.gs.auth.service.account.private.key.id", AppConf.getConfig("gcloud_private_secret_id")) case "oci" => - sc.hadoopConfiguration.set("fs.s3a.awsAccessKeyId", AppConf.getConfig(accountKey.getOrElse("aws_storage_key"))); - sc.hadoopConfiguration.set("fs.s3a.awsSecretAccessKey", AppConf.getConfig(accountSecret.getOrElse("aws_storage_secret"))); - // sc.hadoopConfiguration.set("fs.s3a.endpoint", AppConf.getConfig(accountSecret.getOrElse("cloud_storage_endpoint_with_protocol"))); + sc.hadoopConfiguration.set("fs.s3a.access.key", AppConf.getConfig(accountKey.getOrElse("aws_storage_key"))); + sc.hadoopConfiguration.set("fs.s3a.secret.key", AppConf.getConfig(accountSecret.getOrElse("aws_storage_secret"))); + sc.hadoopConfiguration.set("fs.s3a.endpoint", AppConf.getConfig(accountSecret.getOrElse("cloud_storage_endpoint_with_protocol"))); case _ => // Do nothing } diff --git a/analytics-core/src/test/scala/org/ekstep/analytics/framework/util/TestCommonUtil.scala b/analytics-core/src/test/scala/org/ekstep/analytics/framework/util/TestCommonUtil.scala index 267ef37..ab1772e 100644 --- a/analytics-core/src/test/scala/org/ekstep/analytics/framework/util/TestCommonUtil.scala +++ b/analytics-core/src/test/scala/org/ekstep/analytics/framework/util/TestCommonUtil.scala @@ -317,8 +317,8 @@ class TestCommonUtil extends BaseSpec { azureStorageConf.get("fs.azure.account.key.azure-test-key.blob.core.windows.net") should be("azure-test-secret") val s3StorageConf = CommonUtil.setStorageConf("s3", Option("aws_storage_key"), Option("aws_storage_secret")) - s3StorageConf.get("fs.s3a.awsAccessKeyId") should be("aws-test-key") - s3StorageConf.get("fs.s3a.awsSecretAccessKey") should be("aws-test-secret") + s3StorageConf.get("fs.s3a.access.key") should be("aws-test-key") + s3StorageConf.get("fs.s3a.secret.key") should be("aws-test-secret") val fileUtil = new HadoopFileUtil; val copiedFile = fileUtil.copy("src/test/resources/sample_telemetry.log", "src/test/resources/sample_telemetry.json", sc.hadoopConfiguration) From dfc8bd22ef7473346466ffc8de0ab34fcbf873ed Mon Sep 17 00:00:00 2001 From: sowmya-dixit Date: Wed, 8 May 2024 13:58:56 +0530 Subject: [PATCH 4/4] fix: MergeUtil issue fixes for OCI --- .../org/ekstep/analytics/framework/util/MergeUtil.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/MergeUtil.scala b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/MergeUtil.scala index 8013d23..1b415e3 100644 --- a/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/MergeUtil.scala +++ b/analytics-core/src/main/scala/org/ekstep/analytics/framework/util/MergeUtil.scala @@ -30,8 +30,8 @@ class MergeUtil { }) mergeConfig.merge.files.foreach(filePaths => { val isPrivate = mergeConfig.reportFileAccess.getOrElse(true) - val storageKey= if(isPrivate) "azure_storage_key" else "druid_storage_account_key" - val storageSecret= if(isPrivate) "azure_storage_secret" else "druid_storage_account_secret" + val storageKey= if(isPrivate) "cloud_storage_key" else "druid_storage_account_key" + val storageSecret= if(isPrivate) "cloud_storage_secret" else "druid_storage_account_secret" val metricLabels= mergeConfig.metricLabels.getOrElse(List()) val path = new Path(filePaths("reportPath")) val postContainer= mergeConfig.postContainer.getOrElse(AppConf.getConfig("druid.report.default.container")) @@ -191,7 +191,7 @@ class MergeUtil { def fetchBlobFile(filePath: String, isPrivate: Boolean, container: String)(implicit sqlContext: SQLContext, fc: FrameworkContext): DataFrame = { val storageService = if (isPrivate) - fc.getStorageService("azure", "azure_storage_key", "azure_storage_secret") + fc.getStorageService("azure", "cloud_storage_key", "cloud_storage_secret") else { fc.getStorageService("azure", "druid_storage_account_key", "druid_storage_account_secret") } @@ -205,7 +205,7 @@ class MergeUtil { def fetchOSSFile(filePath: String, isPrivate: Boolean, container: String)(implicit sqlContext: SQLContext, fc: FrameworkContext): DataFrame = { val storageService = if (isPrivate) - fc.getStorageService("oci", "aws_storage_key", "aws_storage_secret") + fc.getStorageService("oci", "cloud_storage_key", "cloud_storage_secret") else { fc.getStorageService("oci", "druid_storage_account_key", "druid_storage_account_secret") }