From 94403686df7a8311ffca21f067165969b87e0d2c Mon Sep 17 00:00:00 2001 From: davitbzh <44586065+davitbzh@users.noreply.github.com> Date: Tue, 4 Apr 2023 22:48:56 +0200 Subject: [PATCH] [FSTORE-789] multi modular hsfs java client (#975) multi modular hsfs java client --- .github/workflows/mkdocs-master.yml | 8 +- .github/workflows/mkdocs-release.yml | 8 +- java/hsfs/pom.xml | 28 ++++ .../com/logicalclocks/hsfs/DataFormat.java | 0 .../hsfs/DeltaStreamerJobConf.java | 0 .../hsfs/EntityEndpointType.java | 0 .../hsfs/ExternalDataFormat.java | 0 .../java/com/logicalclocks/hsfs/Feature.java | 0 .../logicalclocks/hsfs/FeatureGroupBase.java | 0 .../hsfs/FeatureGroupBaseForApi.java | 0 .../hsfs/FeatureGroupCommit.java | 0 .../logicalclocks/hsfs/FeatureStoreBase.java | 0 .../hsfs/FeatureStoreException.java | 0 .../com/logicalclocks/hsfs/FeatureType.java | 0 .../logicalclocks/hsfs/FeatureViewBase.java | 0 .../hsfs/HopsworksConnectionBase.java | 0 .../logicalclocks/hsfs/HudiOperationType.java | 0 .../logicalclocks/hsfs/JobConfiguration.java | 0 .../java/com/logicalclocks/hsfs/Project.java | 0 .../com/logicalclocks/hsfs/SecretStore.java | 0 .../logicalclocks/hsfs/SecurityProtocol.java | 0 .../java/com/logicalclocks/hsfs/Split.java | 0 .../SslEndpointIdentificationAlgorithm.java | 0 .../logicalclocks/hsfs/StatisticsConfig.java | 0 .../java/com/logicalclocks/hsfs/Storage.java | 0 .../logicalclocks/hsfs/StorageConnector.java | 14 +- .../hsfs/StorageConnectorType.java | 0 .../logicalclocks/hsfs/TimeTravelFormat.java | 0 .../hsfs/TrainingDatasetBase.java | 0 .../hsfs/TrainingDatasetFeature.java | 0 .../hsfs/TrainingDatasetType.java | 0 .../hsfs/TransformationFunction.java | 0 .../hsfs/constructor/FeatureGroupAlias.java | 0 .../hsfs/constructor/Filter.java | 0 .../hsfs/constructor/FilterLogic.java | 0 .../hsfs/constructor/FsQueryBase.java | 0 .../logicalclocks/hsfs/constructor/Join.java | 0 .../hsfs/constructor/JoinType.java | 0 .../PreparedStatementParameter.java | 0 .../hsfs/constructor/QueryBase.java | 0 .../constructor/ServingPreparedStatement.java | 0 .../hsfs/constructor/SqlFilterCondition.java | 0 .../hsfs/constructor/SqlFilterLogic.java | 0 .../logicalclocks/hsfs/engine/CodeEngine.java | 0 .../hsfs/engine/FeatureGroupEngineBase.java | 2 +- .../hsfs/engine/FeatureGroupUtils.java | 8 +- .../hsfs/engine/FeatureViewEngineBase.java | 8 +- .../hsfs/engine/VectorServer.java | 0 .../hsfs/metadata/AuthorizationHandler.java | 0 .../com/logicalclocks/hsfs/metadata/Code.java | 0 .../logicalclocks/hsfs/metadata/CodeApi.java | 0 .../hsfs/metadata/Credentials.java | 0 .../hsfs/metadata/FeatureGroupApi.java | 0 .../hsfs/metadata/FeatureStoreApi.java | 0 .../hsfs/metadata/FeatureViewApi.java | 0 .../hsfs/metadata/HopsworksClient.java | 0 .../metadata/HopsworksExternalClient.java | 0 .../metadata/HopsworksHostnameVerifier.java | 0 .../hsfs/metadata/HopsworksHttpClient.java | 0 .../metadata/HopsworksInternalClient.java | 0 .../hsfs/metadata/InternalException.java | 0 .../logicalclocks/hsfs/metadata/KafkaApi.java | 0 .../hsfs/metadata/KafkaClusterInfo.java | 0 .../hsfs/metadata/OnDemandOptions.java | 0 .../logicalclocks/hsfs/metadata/Option.java | 0 .../hsfs/metadata/PartitionDetails.java | 0 .../hsfs/metadata/ProjectApi.java | 0 .../hsfs/metadata/QueryConstructorApi.java | 2 +- .../logicalclocks/hsfs/metadata/RestDto.java | 0 .../hsfs/metadata/SplitStatistics.java | 0 .../hsfs/metadata/Statistics.java | 0 .../hsfs/metadata/StatisticsApi.java | 13 +- .../hsfs/metadata/StorageConnectorApi.java | 0 .../logicalclocks/hsfs/metadata/Subject.java | 0 .../com/logicalclocks/hsfs/metadata/Tags.java | 0 .../logicalclocks/hsfs/metadata/TagsApi.java | 12 +- .../hsfs/metadata/TrainingDatasetApi.java | 0 .../TransformationFunctionAttached.java | 0 .../hsfs/metadata/UnauthorizedException.java | 0 .../com/logicalclocks/hsfs/metadata/User.java | 0 .../logicalclocks/hsfs/util/Constants.java | 0 .../hsfs}/TestHopsworksExternalClient.java | 3 +- .../hsfs/metadata/TestHopsworksClient.java | 2 +- .../hsfs/metadata/TestTagsApi.java | 0 java/pom.xml | 158 +++++------------- java/spark/pom.xml | 158 ++++++++++++++++++ .../hsfs/spark/ExternalFeatureGroup.java | 6 +- .../hsfs/spark/FeatureGroup.java | 6 +- .../hsfs/spark/FeatureStore.java | 33 ++-- .../logicalclocks/hsfs/spark/FeatureView.java | 8 +- .../hsfs/spark/HopsworksConnection.java | 2 +- .../logicalclocks/hsfs/spark/MainClass.java | 4 +- .../hsfs/spark/StreamFeatureGroup.java | 6 +- .../hsfs/spark/TrainingDataset.java | 8 +- .../hsfs/spark/TrainingDatasetBundle.java | 2 +- .../hsfs/spark/constructor/FsQuery.java | 2 +- .../hsfs/spark/constructor/Query.java | 4 +- .../hsfs/spark/engine/FeatureGroupEngine.java | 6 +- .../hsfs/spark/engine/FeatureViewEngine.java | 2 +- .../hsfs/spark/engine/SparkEngine.java | 6 +- .../hsfs/spark/engine/StatisticsEngine.java | 0 .../spark/engine/TrainingDatasetEngine.java | 2 +- .../spark/engine/TrainingDatasetUtils.java | 0 .../hudi/DeltaStreamerAvroDeserializer.java | 0 .../engine/hudi/DeltaStreamerConfig.java | 0 .../engine/hudi/DeltaStreamerKafkaSource.java | 0 .../hudi/DeltaStreamerSchemaProvider.java | 0 .../engine/hudi/DeltaStreamerTransformer.java | 0 .../hsfs/spark/engine/hudi/HudiEngine.java | 12 +- .../spark/util/StorageConnectorUtils.java | 11 +- .../hsfs/spark/TestExternalFeatureGroup.java | 0 .../logicalclocks/hsfs/spark/TestFeature.java | 0 .../hsfs/spark/TestFeatureGroup.java | 0 .../hsfs/spark}/TestStorageConnector.java | 14 +- .../spark/engine/TestFeatureViewEngine.java | 0 .../hsfs/spark/engine/TestHudiEngine.java | 0 .../hsfs/spark/engine/TestSparkEngine.java | 0 .../test/resources/hadoop/bin/winutils.exe | Bin 0 -> 112640 bytes .../src/test/resources/system.properties | 1 + 119 files changed, 338 insertions(+), 221 deletions(-) create mode 100644 java/hsfs/pom.xml rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/DataFormat.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/DeltaStreamerJobConf.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/EntityEndpointType.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/ExternalDataFormat.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/Feature.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/FeatureGroupBase.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/FeatureGroupBaseForApi.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/FeatureGroupCommit.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/FeatureStoreBase.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/FeatureStoreException.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/FeatureType.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/FeatureViewBase.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/HopsworksConnectionBase.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/HudiOperationType.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/JobConfiguration.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/Project.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/SecretStore.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/SecurityProtocol.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/Split.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/SslEndpointIdentificationAlgorithm.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/StatisticsConfig.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/Storage.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/StorageConnector.java (96%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/StorageConnectorType.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/TimeTravelFormat.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/TrainingDatasetBase.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/TrainingDatasetFeature.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/TrainingDatasetType.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/TransformationFunction.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/FeatureGroupAlias.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/Filter.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/FilterLogic.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/FsQueryBase.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/Join.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/JoinType.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/PreparedStatementParameter.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/QueryBase.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/ServingPreparedStatement.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/SqlFilterCondition.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/constructor/SqlFilterLogic.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/engine/CodeEngine.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupEngineBase.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupUtils.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/engine/FeatureViewEngineBase.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/engine/VectorServer.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/AuthorizationHandler.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/Code.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/CodeApi.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/Credentials.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/FeatureGroupApi.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/FeatureStoreApi.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/FeatureViewApi.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksClient.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksExternalClient.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksHostnameVerifier.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksHttpClient.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksInternalClient.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/InternalException.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/KafkaApi.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/KafkaClusterInfo.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/OnDemandOptions.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/Option.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/PartitionDetails.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/ProjectApi.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/QueryConstructorApi.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/RestDto.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/SplitStatistics.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/Statistics.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/StatisticsApi.java (93%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/StorageConnectorApi.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/Subject.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/Tags.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/TagsApi.java (96%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/TrainingDatasetApi.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/TransformationFunctionAttached.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/UnauthorizedException.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/metadata/User.java (100%) rename java/{ => hsfs}/src/main/java/com/logicalclocks/hsfs/util/Constants.java (100%) rename java/{src/test/java/com/logicalclocks => hsfs/src/test/java/com/logicalclocks/hsfs}/TestHopsworksExternalClient.java (97%) rename java/{ => hsfs}/src/test/java/com/logicalclocks/hsfs/metadata/TestHopsworksClient.java (97%) rename java/{ => hsfs}/src/test/java/com/logicalclocks/hsfs/metadata/TestTagsApi.java (100%) create mode 100644 java/spark/pom.xml rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/ExternalFeatureGroup.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/FeatureGroup.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/FeatureStore.java (98%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/FeatureView.java (99%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/HopsworksConnection.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/MainClass.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/StreamFeatureGroup.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/TrainingDataset.java (99%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/TrainingDatasetBundle.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/constructor/FsQuery.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/constructor/Query.java (94%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/FeatureGroupEngine.java (99%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/FeatureViewEngine.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/SparkEngine.java (99%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/StatisticsEngine.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetEngine.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetUtils.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerAvroDeserializer.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerConfig.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerKafkaSource.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerSchemaProvider.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerTransformer.java (100%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/HudiEngine.java (97%) rename java/{ => spark}/src/main/java/com/logicalclocks/hsfs/spark/util/StorageConnectorUtils.java (97%) rename java/{ => spark}/src/test/java/com/logicalclocks/hsfs/spark/TestExternalFeatureGroup.java (100%) rename java/{ => spark}/src/test/java/com/logicalclocks/hsfs/spark/TestFeature.java (100%) rename java/{ => spark}/src/test/java/com/logicalclocks/hsfs/spark/TestFeatureGroup.java (100%) rename java/{src/test/java/com/logicalclocks => spark/src/test/java/com/logicalclocks/hsfs/spark}/TestStorageConnector.java (94%) rename java/{ => spark}/src/test/java/com/logicalclocks/hsfs/spark/engine/TestFeatureViewEngine.java (100%) rename java/{ => spark}/src/test/java/com/logicalclocks/hsfs/spark/engine/TestHudiEngine.java (100%) rename java/{ => spark}/src/test/java/com/logicalclocks/hsfs/spark/engine/TestSparkEngine.java (100%) create mode 100644 java/spark/src/test/resources/hadoop/bin/winutils.exe create mode 100644 java/spark/src/test/resources/system.properties diff --git a/.github/workflows/mkdocs-master.yml b/.github/workflows/mkdocs-master.yml index 10ad5ad6f2..0ea51b9216 100644 --- a/.github/workflows/mkdocs-master.yml +++ b/.github/workflows/mkdocs-master.yml @@ -35,9 +35,15 @@ jobs: restore-keys: | ${{ runner.os }}-maven- + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'adopt' + - name: Build java doc documentation working-directory: ./java - run: mvn clean package javadoc:javadoc -DskipTests && cp -r target/apidocs ../docs/javadoc + run: mvn clean install javadoc:javadoc javadoc:aggregate -DskipTests && cp -r target/site/apidocs ../docs/javadoc - name: setup git run: | diff --git a/.github/workflows/mkdocs-release.yml b/.github/workflows/mkdocs-release.yml index 1fdc28288c..f80e9ad2f4 100644 --- a/.github/workflows/mkdocs-release.yml +++ b/.github/workflows/mkdocs-release.yml @@ -42,9 +42,15 @@ jobs: restore-keys: | ${{ runner.os }}-maven- + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'adopt' + - name: Build java doc documentation working-directory: ./java - run: mvn clean package javadoc:javadoc -DskipTests && cp -r target/apidocs ../docs/javadoc + run: mvn clean install javadoc:javadoc javadoc:aggregate -DskipTests && cp -r target/site/apidocs ../docs/javadoc - name: setup git run: | diff --git a/java/hsfs/pom.xml b/java/hsfs/pom.xml new file mode 100644 index 0000000000..319f4a6794 --- /dev/null +++ b/java/hsfs/pom.xml @@ -0,0 +1,28 @@ + + + + hsfs-sdk + com.logicalclocks + 3.2.0-SNAPSHOT + + 4.0.0 + + hsfs + + + + 2.2.11 + + + + + + javax.xml.bind + jaxb-api + ${javax.version} + provided + + + diff --git a/java/src/main/java/com/logicalclocks/hsfs/DataFormat.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/DataFormat.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/DataFormat.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/DataFormat.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/DeltaStreamerJobConf.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/DeltaStreamerJobConf.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/DeltaStreamerJobConf.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/DeltaStreamerJobConf.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/EntityEndpointType.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/EntityEndpointType.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/EntityEndpointType.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/EntityEndpointType.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/ExternalDataFormat.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/ExternalDataFormat.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/ExternalDataFormat.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/ExternalDataFormat.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/Feature.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/Feature.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/Feature.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/Feature.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/FeatureGroupBase.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureGroupBase.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/FeatureGroupBase.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureGroupBase.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/FeatureGroupBaseForApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureGroupBaseForApi.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/FeatureGroupBaseForApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureGroupBaseForApi.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/FeatureGroupCommit.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureGroupCommit.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/FeatureGroupCommit.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureGroupCommit.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/FeatureStoreBase.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureStoreBase.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/FeatureStoreBase.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureStoreBase.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/FeatureStoreException.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureStoreException.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/FeatureStoreException.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureStoreException.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/FeatureType.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureType.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/FeatureType.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureType.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/FeatureViewBase.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureViewBase.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/FeatureViewBase.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/FeatureViewBase.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/HopsworksConnectionBase.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/HopsworksConnectionBase.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/HopsworksConnectionBase.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/HopsworksConnectionBase.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/HudiOperationType.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/HudiOperationType.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/HudiOperationType.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/HudiOperationType.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/JobConfiguration.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/JobConfiguration.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/JobConfiguration.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/JobConfiguration.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/Project.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/Project.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/Project.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/Project.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/SecretStore.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/SecretStore.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/SecretStore.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/SecretStore.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/SecurityProtocol.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/SecurityProtocol.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/SecurityProtocol.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/SecurityProtocol.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/Split.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/Split.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/Split.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/Split.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/SslEndpointIdentificationAlgorithm.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/SslEndpointIdentificationAlgorithm.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/SslEndpointIdentificationAlgorithm.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/SslEndpointIdentificationAlgorithm.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/StatisticsConfig.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/StatisticsConfig.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/StatisticsConfig.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/StatisticsConfig.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/Storage.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/Storage.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/Storage.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/Storage.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/StorageConnector.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/StorageConnector.java similarity index 96% rename from java/src/main/java/com/logicalclocks/hsfs/StorageConnector.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/StorageConnector.java index 91c6b42154..9eeb0c82eb 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/StorageConnector.java +++ b/java/hsfs/src/main/java/com/logicalclocks/hsfs/StorageConnector.java @@ -23,9 +23,8 @@ import com.google.common.base.Strings; import com.logicalclocks.hsfs.metadata.Option; import com.logicalclocks.hsfs.metadata.StorageConnectorApi; - import com.logicalclocks.hsfs.util.Constants; -import com.logicalclocks.hsfs.spark.engine.SparkEngine; + import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -33,10 +32,7 @@ import lombok.ToString; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.time.Instant; -import java.util.Base64; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -491,17 +487,11 @@ public static class BigqueryConnector extends StorageConnector { /** * Set spark options specific to BigQuery. * @return Map - * @throws IOException IOException */ @Override - public Map sparkOptions() throws IOException { + public Map sparkOptions() { Map options = new HashMap<>(); - // Base64 encode the credentials file - String localKeyPath = SparkEngine.getInstance().addFile(keyPath); - byte[] fileContent = Files.readAllBytes(Paths.get(localKeyPath)); - options.put(Constants.BIGQ_CREDENTIALS, Base64.getEncoder().encodeToString(fileContent)); - options.put(Constants.BIGQ_PARENT_PROJECT, parentProject); if (!Strings.isNullOrEmpty(materializationDataset)) { options.put(Constants.BIGQ_MATERIAL_DATASET, materializationDataset); diff --git a/java/src/main/java/com/logicalclocks/hsfs/StorageConnectorType.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/StorageConnectorType.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/StorageConnectorType.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/StorageConnectorType.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/TimeTravelFormat.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/TimeTravelFormat.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/TimeTravelFormat.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/TimeTravelFormat.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/TrainingDatasetBase.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/TrainingDatasetBase.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/TrainingDatasetBase.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/TrainingDatasetBase.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/TrainingDatasetFeature.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/TrainingDatasetFeature.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/TrainingDatasetFeature.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/TrainingDatasetFeature.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/TrainingDatasetType.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/TrainingDatasetType.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/TrainingDatasetType.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/TrainingDatasetType.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/TransformationFunction.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/TransformationFunction.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/TransformationFunction.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/TransformationFunction.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/FeatureGroupAlias.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/FeatureGroupAlias.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/FeatureGroupAlias.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/FeatureGroupAlias.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/Filter.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/Filter.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/Filter.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/Filter.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/FilterLogic.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/FilterLogic.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/FilterLogic.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/FilterLogic.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/FsQueryBase.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/FsQueryBase.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/FsQueryBase.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/FsQueryBase.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/Join.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/Join.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/Join.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/Join.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/JoinType.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/JoinType.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/JoinType.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/JoinType.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/PreparedStatementParameter.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/PreparedStatementParameter.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/PreparedStatementParameter.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/PreparedStatementParameter.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/QueryBase.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/QueryBase.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/QueryBase.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/QueryBase.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/ServingPreparedStatement.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/ServingPreparedStatement.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/ServingPreparedStatement.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/ServingPreparedStatement.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/SqlFilterCondition.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/SqlFilterCondition.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/SqlFilterCondition.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/SqlFilterCondition.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/constructor/SqlFilterLogic.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/SqlFilterLogic.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/constructor/SqlFilterLogic.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/constructor/SqlFilterLogic.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/engine/CodeEngine.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/CodeEngine.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/engine/CodeEngine.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/CodeEngine.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupEngineBase.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupEngineBase.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupEngineBase.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupEngineBase.java index a2b0ee73c4..bbfeb738e5 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupEngineBase.java +++ b/java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupEngineBase.java @@ -18,9 +18,9 @@ package com.logicalclocks.hsfs.engine; import com.logicalclocks.hsfs.metadata.FeatureGroupApi; -import com.logicalclocks.hsfs.FeatureGroupBase; import com.logicalclocks.hsfs.metadata.HopsworksClient; import com.logicalclocks.hsfs.metadata.TagsApi; +import com.logicalclocks.hsfs.FeatureGroupBase; import com.logicalclocks.hsfs.EntityEndpointType; import com.logicalclocks.hsfs.Feature; import com.logicalclocks.hsfs.FeatureStoreException; diff --git a/java/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupUtils.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupUtils.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupUtils.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupUtils.java index 1aa89eb856..aa5b7eaaa3 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupUtils.java +++ b/java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/FeatureGroupUtils.java @@ -17,16 +17,16 @@ package com.logicalclocks.hsfs.engine; -import com.logicalclocks.hsfs.Feature; -import com.logicalclocks.hsfs.FeatureStoreBase; import com.logicalclocks.hsfs.metadata.FeatureGroupApi; -import com.logicalclocks.hsfs.FeatureGroupBase; import com.logicalclocks.hsfs.metadata.HopsworksClient; import com.logicalclocks.hsfs.metadata.KafkaApi; +import com.logicalclocks.hsfs.metadata.Subject; +import com.logicalclocks.hsfs.Feature; +import com.logicalclocks.hsfs.FeatureStoreBase; +import com.logicalclocks.hsfs.FeatureGroupBase; import com.logicalclocks.hsfs.FeatureGroupCommit; import com.logicalclocks.hsfs.FeatureStoreException; -import com.logicalclocks.hsfs.metadata.Subject; import lombok.SneakyThrows; import org.apache.avro.Schema; import org.apache.avro.SchemaBuilder; diff --git a/java/src/main/java/com/logicalclocks/hsfs/engine/FeatureViewEngineBase.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/FeatureViewEngineBase.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/engine/FeatureViewEngineBase.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/FeatureViewEngineBase.java index 175a9fb053..2780f6eeee 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/engine/FeatureViewEngineBase.java +++ b/java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/FeatureViewEngineBase.java @@ -20,15 +20,15 @@ import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.logicalclocks.hsfs.constructor.Join; +import com.logicalclocks.hsfs.constructor.QueryBase; +import com.logicalclocks.hsfs.metadata.FeatureViewApi; +import com.logicalclocks.hsfs.metadata.TagsApi; import com.logicalclocks.hsfs.Feature; import com.logicalclocks.hsfs.FeatureGroupBaseForApi; import com.logicalclocks.hsfs.Split; import com.logicalclocks.hsfs.TrainingDatasetBase; -import com.logicalclocks.hsfs.constructor.Join; -import com.logicalclocks.hsfs.constructor.QueryBase; import com.logicalclocks.hsfs.FeatureGroupBase; -import com.logicalclocks.hsfs.metadata.FeatureViewApi; -import com.logicalclocks.hsfs.metadata.TagsApi; import com.logicalclocks.hsfs.EntityEndpointType; import com.logicalclocks.hsfs.FeatureStoreBase; import com.logicalclocks.hsfs.FeatureStoreException; diff --git a/java/src/main/java/com/logicalclocks/hsfs/engine/VectorServer.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/VectorServer.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/engine/VectorServer.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/engine/VectorServer.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/AuthorizationHandler.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/AuthorizationHandler.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/AuthorizationHandler.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/AuthorizationHandler.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/Code.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Code.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/Code.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Code.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/CodeApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/CodeApi.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/CodeApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/CodeApi.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/Credentials.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Credentials.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/Credentials.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Credentials.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/FeatureGroupApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/FeatureGroupApi.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/FeatureGroupApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/FeatureGroupApi.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/FeatureStoreApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/FeatureStoreApi.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/FeatureStoreApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/FeatureStoreApi.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/FeatureViewApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/FeatureViewApi.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/FeatureViewApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/FeatureViewApi.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksClient.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksClient.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksClient.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksClient.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksExternalClient.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksExternalClient.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksExternalClient.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksExternalClient.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksHostnameVerifier.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksHostnameVerifier.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksHostnameVerifier.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksHostnameVerifier.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksHttpClient.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksHttpClient.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksHttpClient.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksHttpClient.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksInternalClient.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksInternalClient.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksInternalClient.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/HopsworksInternalClient.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/InternalException.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/InternalException.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/InternalException.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/InternalException.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/KafkaApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/KafkaApi.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/KafkaApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/KafkaApi.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/KafkaClusterInfo.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/KafkaClusterInfo.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/KafkaClusterInfo.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/KafkaClusterInfo.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/OnDemandOptions.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/OnDemandOptions.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/OnDemandOptions.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/OnDemandOptions.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/Option.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Option.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/Option.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Option.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/PartitionDetails.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/PartitionDetails.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/PartitionDetails.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/PartitionDetails.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/ProjectApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/ProjectApi.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/ProjectApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/ProjectApi.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/QueryConstructorApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/QueryConstructorApi.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/QueryConstructorApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/QueryConstructorApi.java index 2486ed72a3..95c4035836 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/metadata/QueryConstructorApi.java +++ b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/QueryConstructorApi.java @@ -18,10 +18,10 @@ package com.logicalclocks.hsfs.metadata; import com.damnhandy.uri.template.UriTemplate; -import com.logicalclocks.hsfs.FeatureGroupBase; import com.logicalclocks.hsfs.constructor.FeatureGroupAlias; import com.logicalclocks.hsfs.constructor.FsQueryBase; import com.logicalclocks.hsfs.constructor.QueryBase; +import com.logicalclocks.hsfs.FeatureGroupBase; import com.logicalclocks.hsfs.FeatureStoreBase; import com.logicalclocks.hsfs.FeatureStoreException; import org.apache.http.HttpHeaders; diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/RestDto.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/RestDto.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/RestDto.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/RestDto.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/SplitStatistics.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/SplitStatistics.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/SplitStatistics.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/SplitStatistics.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/Statistics.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Statistics.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/Statistics.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Statistics.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/StatisticsApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/StatisticsApi.java similarity index 93% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/StatisticsApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/StatisticsApi.java index 874c55fb75..a2725e4f7c 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/metadata/StatisticsApi.java +++ b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/StatisticsApi.java @@ -31,9 +31,6 @@ import java.io.IOException; -import static com.logicalclocks.hsfs.metadata.HopsworksClient.PROJECT_PATH; -import static com.logicalclocks.hsfs.metadata.HopsworksClient.getInstance; - public class StatisticsApi { private static final String ENTITY_ROOT_PATH = "{/entityType}"; @@ -65,7 +62,7 @@ public Statistics post(TrainingDatasetBase trainingDatasetBase, Statistics stati private Statistics post(Integer projectId, Integer featurestoreId, Integer entityId, Statistics statistics) throws FeatureStoreException, IOException { - String pathTemplate = PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + STATISTICS_PATH; + String pathTemplate = HopsworksClient.PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + STATISTICS_PATH; String uri = UriTemplate.fromTemplate(pathTemplate) .set("projectId", projectId) @@ -79,7 +76,7 @@ private Statistics post(Integer projectId, Integer featurestoreId, Integer entit public Statistics post(FeatureViewBase featureViewBase, Integer trainingDataVersion, Statistics statistics) throws FeatureStoreException, IOException { - String pathTemplate = PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + FV_STATISTICS_PATH; + String pathTemplate = HopsworksClient.PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + FV_STATISTICS_PATH; String uri = UriTemplate.fromTemplate(pathTemplate) .set("projectId", featureViewBase.getFeatureStore().getProjectId()) @@ -92,7 +89,7 @@ public Statistics post(FeatureViewBase featureViewBase, } private Statistics post(String uri, Statistics statistics) throws FeatureStoreException, IOException { - HopsworksClient hopsworksClient = getInstance(); + HopsworksClient hopsworksClient = HopsworksClient.getInstance(); LOGGER.info("Sending metadata request: " + uri); HttpPost postRequest = new HttpPost(uri); postRequest.setEntity(hopsworksClient.buildStringEntity(statistics)); @@ -114,7 +111,7 @@ public Statistics get(TrainingDatasetBase trainingDatasetBase, String commitTime private Statistics get(Integer projectId, Integer featurestoreId, Integer entityId, String commitTime) throws FeatureStoreException, IOException { HopsworksClient hopsworksClient = HopsworksClient.getInstance(); - String pathTemplate = PROJECT_PATH + String pathTemplate = HopsworksClient.PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + STATISTICS_PATH; @@ -152,7 +149,7 @@ public Statistics getLast(TrainingDatasetBase trainingDatasetBase) throws Featur private Statistics getLast(Integer projectId, Integer featurestoreId, Integer entityId) throws FeatureStoreException, IOException { HopsworksClient hopsworksClient = HopsworksClient.getInstance(); - String pathTemplate = PROJECT_PATH + String pathTemplate = HopsworksClient.PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + STATISTICS_PATH; diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/StorageConnectorApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/StorageConnectorApi.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/StorageConnectorApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/StorageConnectorApi.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/Subject.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Subject.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/Subject.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Subject.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/Tags.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Tags.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/Tags.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/Tags.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/TagsApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/TagsApi.java similarity index 96% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/TagsApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/TagsApi.java index 6c6b744c94..c6f5cb7470 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/metadata/TagsApi.java +++ b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/TagsApi.java @@ -38,16 +38,14 @@ import java.util.Map; import java.util.Optional; -import static com.logicalclocks.hsfs.metadata.HopsworksClient.PROJECT_PATH; - public class TagsApi { public static final String ENTITY_ROOT_PATH = "{/entityType}"; public static final String ENTITY_ID_PATH = ENTITY_ROOT_PATH + "{/entityId}"; public static final String TAGS_PATH = ENTITY_ID_PATH + "/tags{/name}{?value}"; - public static final String FV_TAGS_PATH = PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + public static final String FV_TAGS_PATH = HopsworksClient.PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + "/featureview{/fvName}/version{/fvVersion}/tags{/name}"; - public static final String FV_TD_TAGS_PATH = PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + public static final String FV_TD_TAGS_PATH = HopsworksClient.PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + "/featureview{/fvName}/version{/fvVersion}" + "/trainingdatasets/version{/tdVersion}/tags{/name}"; @@ -62,7 +60,7 @@ public TagsApi(@NonNull EntityEndpointType entityType) { private void add(Integer projectId, Integer featurestoreId, Integer entityId, String name, Object value) throws FeatureStoreException, IOException { - String pathTemplate = PROJECT_PATH + String pathTemplate = HopsworksClient.PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + TAGS_PATH; @@ -147,7 +145,7 @@ private UriTemplate getFvTdUriTemplate(FeatureViewBase featureViewBase, Integer private Map get(Integer projectId, Integer featurestoreId, Integer entityId, Optional name) throws FeatureStoreException, IOException { - String pathTemplate = PROJECT_PATH + String pathTemplate = HopsworksClient.PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + TAGS_PATH; @@ -238,7 +236,7 @@ public Object parseTagValue(ObjectMapper objectMapper, Object value) throws IOEx private void deleteTag(Integer projectId, Integer featurestoreId, Integer entityId, String name) throws FeatureStoreException, IOException { - String pathTemplate = PROJECT_PATH + String pathTemplate = HopsworksClient.PROJECT_PATH + FeatureStoreApi.FEATURE_STORE_PATH + TAGS_PATH; diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/TrainingDatasetApi.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/TrainingDatasetApi.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/TrainingDatasetApi.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/TrainingDatasetApi.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/TransformationFunctionAttached.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/TransformationFunctionAttached.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/TransformationFunctionAttached.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/TransformationFunctionAttached.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/UnauthorizedException.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/UnauthorizedException.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/UnauthorizedException.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/UnauthorizedException.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/metadata/User.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/User.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/metadata/User.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/metadata/User.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/util/Constants.java b/java/hsfs/src/main/java/com/logicalclocks/hsfs/util/Constants.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/util/Constants.java rename to java/hsfs/src/main/java/com/logicalclocks/hsfs/util/Constants.java diff --git a/java/src/test/java/com/logicalclocks/TestHopsworksExternalClient.java b/java/hsfs/src/test/java/com/logicalclocks/hsfs/TestHopsworksExternalClient.java similarity index 97% rename from java/src/test/java/com/logicalclocks/TestHopsworksExternalClient.java rename to java/hsfs/src/test/java/com/logicalclocks/hsfs/TestHopsworksExternalClient.java index d330a9abb4..379f1a0459 100644 --- a/java/src/test/java/com/logicalclocks/TestHopsworksExternalClient.java +++ b/java/hsfs/src/test/java/com/logicalclocks/hsfs/TestHopsworksExternalClient.java @@ -14,10 +14,9 @@ * See the License for the specific language governing permissions and limitations under the License. * */ -package com.logicalclocks; +package com.logicalclocks.hsfs; import com.logicalclocks.hsfs.metadata.HopsworksExternalClient; -import com.logicalclocks.hsfs.FeatureStoreException; import com.logicalclocks.hsfs.metadata.Credentials; import io.specto.hoverfly.junit.core.SimulationSource; import io.specto.hoverfly.junit.dsl.HttpBodyConverter; diff --git a/java/src/test/java/com/logicalclocks/hsfs/metadata/TestHopsworksClient.java b/java/hsfs/src/test/java/com/logicalclocks/hsfs/metadata/TestHopsworksClient.java similarity index 97% rename from java/src/test/java/com/logicalclocks/hsfs/metadata/TestHopsworksClient.java rename to java/hsfs/src/test/java/com/logicalclocks/hsfs/metadata/TestHopsworksClient.java index 266bffae77..6d27912fa2 100644 --- a/java/src/test/java/com/logicalclocks/hsfs/metadata/TestHopsworksClient.java +++ b/java/hsfs/src/test/java/com/logicalclocks/hsfs/metadata/TestHopsworksClient.java @@ -42,7 +42,7 @@ public void testStringEntitySerialization() throws IOException { Assertions.assertEquals("Content-Type: application/json; charset=UTF-8", stringEntity.getContentType().toString()); - String json = IOUtils.toString(stringEntity.getContent(), StandardCharsets.UTF_8); + String json = IOUtils.toString(stringEntity.getContent(), String.valueOf(StandardCharsets.UTF_8)); Assertions.assertEquals("{\"email\":\"test@test.com\",\"firstName\":\"test\",\"lastName\":\"de la Rúa Martínez\"}", json); } diff --git a/java/src/test/java/com/logicalclocks/hsfs/metadata/TestTagsApi.java b/java/hsfs/src/test/java/com/logicalclocks/hsfs/metadata/TestTagsApi.java similarity index 100% rename from java/src/test/java/com/logicalclocks/hsfs/metadata/TestTagsApi.java rename to java/hsfs/src/test/java/com/logicalclocks/hsfs/metadata/TestTagsApi.java diff --git a/java/pom.xml b/java/pom.xml index 3ec65ee63a..5b2083c88e 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -5,8 +5,13 @@ 4.0.0 com.logicalclocks - hsfs + hsfs-sdk + pom 3.2.0-SNAPSHOT + + hsfs + spark + 1.8 @@ -19,7 +24,6 @@ 2.1.8 1.18.10 2.10.0 - 3.1.1.3 1.1.0.6-SNAPSHOT 0.10.0.3 2.10.40 @@ -31,6 +35,7 @@ 5.9.1 2.22.0 4.3.1 + 1.11.1 UTF-8 ${project.basedir}/delombok @@ -43,73 +48,6 @@ ${lombok.version} - - com.logicalclocks - deequ_${scala-short.version} - ${deequ.version} - - - org.apache.spark - * - - - org.scala-lang - * - - - - - - org.apache.spark - spark-core_${scala-short.version} - ${spark.version} - provided - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-databind - - - - - - org.apache.spark - spark-sql_${scala-short.version} - ${spark.version} - provided - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.core - jackson-core - - - - - - org.apache.spark - spark-avro_${scala-short.version} - ${spark.version} - provided - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-databind - - - - com.fasterxml.jackson.core jackson-databind @@ -208,41 +146,6 @@ provided - - - io.hops.hudi - hudi-spark3-bundle_${scala-short.version} - ${hudi.version} - provided - - - org.apache.httpcomponents - * - - - com.fasterxml.jackson.core - * - - - - - - io.hops.hudi - hudi-utilities-bundle_${scala-short.version} - ${hudi.version} - provided - - - org.apache.httpcomponents - * - - - com.fasterxml.jackson.core - * - - - - org.json json @@ -270,19 +173,33 @@ test - - org.apache.spark - spark-hive_${scala-short.version} - ${spark.version} - test - - org.mockito mockito-core ${mockito.version} test + + + + org.apache.avro + avro + ${avro.version} + + + + + org.scala-lang + scala-library + ${scala.version} + + + + + org.apache.commons + commons-io + 1.3.2 + @@ -389,26 +306,29 @@ - org.apache.maven.plugins maven-javadoc-plugin - 3.1.1 + 3.5.0 - 1.8 - 1.8 - ${delombok.output} + **/MainClass.java + + **/beam/constructor/* + **/flink/constructor/* - - attach-javadocs + aggregate - jar + aggregate + site + + + diff --git a/java/spark/pom.xml b/java/spark/pom.xml new file mode 100644 index 0000000000..d6b385d07c --- /dev/null +++ b/java/spark/pom.xml @@ -0,0 +1,158 @@ + + + + + + hsfs-sdk + com.logicalclocks + 3.2.0-SNAPSHOT + + 4.0.0 + + hsfs-spark + + + 3.1.1.3 + + + + + com.logicalclocks + hsfs + ${project.version} + compile + + + javax.xml.bind + jaxb-api + + + + + + com.logicalclocks + deequ_${scala-short.version} + ${deequ.version} + + + org.apache.spark + * + + + org.scala-lang + * + + + + + + org.apache.spark + spark-core_${scala-short.version} + ${spark.version} + provided + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + + + + org.apache.spark + spark-sql_${scala-short.version} + ${spark.version} + provided + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-core + + + + + + org.apache.spark + spark-avro_${scala-short.version} + ${spark.version} + provided + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + + + + + io.hops.hudi + hudi-spark3-bundle_${scala-short.version} + ${hudi.version} + provided + + + org.apache.httpcomponents + * + + + com.fasterxml.jackson.core + * + + + + + + io.hops.hudi + hudi-utilities-bundle_${scala-short.version} + ${hudi.version} + provided + + + org.apache.httpcomponents + * + + + com.fasterxml.jackson.core + * + + + + + + org.apache.spark + spark-hive_${scala-short.version} + ${spark.version} + test + + + diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/ExternalFeatureGroup.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/ExternalFeatureGroup.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/ExternalFeatureGroup.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/ExternalFeatureGroup.java index 6be008ab89..63d9db749f 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/ExternalFeatureGroup.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/ExternalFeatureGroup.java @@ -18,6 +18,9 @@ package com.logicalclocks.hsfs.spark; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.logicalclocks.hsfs.spark.constructor.Query; +import com.logicalclocks.hsfs.spark.engine.FeatureGroupEngine; +import com.logicalclocks.hsfs.spark.engine.StatisticsEngine; import com.logicalclocks.hsfs.EntityEndpointType; import com.logicalclocks.hsfs.ExternalDataFormat; import com.logicalclocks.hsfs.Feature; @@ -33,9 +36,6 @@ import com.logicalclocks.hsfs.FeatureGroupBase; import com.logicalclocks.hsfs.metadata.OnDemandOptions; import com.logicalclocks.hsfs.metadata.Statistics; -import com.logicalclocks.hsfs.spark.constructor.Query; -import com.logicalclocks.hsfs.spark.engine.FeatureGroupEngine; -import com.logicalclocks.hsfs.spark.engine.StatisticsEngine; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/FeatureGroup.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/FeatureGroup.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/FeatureGroup.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/FeatureGroup.java index f36c29a516..c4750e4a58 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/FeatureGroup.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/FeatureGroup.java @@ -19,6 +19,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.logicalclocks.hsfs.spark.constructor.Query; +import com.logicalclocks.hsfs.spark.engine.FeatureGroupEngine; +import com.logicalclocks.hsfs.spark.engine.StatisticsEngine; import com.logicalclocks.hsfs.EntityEndpointType; import com.logicalclocks.hsfs.Feature; @@ -31,9 +34,6 @@ import com.logicalclocks.hsfs.engine.CodeEngine; import com.logicalclocks.hsfs.FeatureGroupBase; import com.logicalclocks.hsfs.metadata.Statistics; -import com.logicalclocks.hsfs.spark.constructor.Query; -import com.logicalclocks.hsfs.spark.engine.FeatureGroupEngine; -import com.logicalclocks.hsfs.spark.engine.StatisticsEngine; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.NonNull; diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/FeatureStore.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/FeatureStore.java similarity index 98% rename from java/src/main/java/com/logicalclocks/hsfs/spark/FeatureStore.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/FeatureStore.java index 3fdd43f06b..9c56c09060 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/FeatureStore.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/FeatureStore.java @@ -17,6 +17,10 @@ package com.logicalclocks.hsfs.spark; +import com.logicalclocks.hsfs.spark.constructor.Query; +import com.logicalclocks.hsfs.spark.engine.FeatureGroupEngine; +import com.logicalclocks.hsfs.spark.engine.FeatureViewEngine; +import com.logicalclocks.hsfs.spark.engine.SparkEngine; import com.logicalclocks.hsfs.FeatureStoreBase; import com.logicalclocks.hsfs.FeatureStoreException; import com.logicalclocks.hsfs.StatisticsConfig; @@ -27,11 +31,6 @@ import com.logicalclocks.hsfs.metadata.StorageConnectorApi; import com.logicalclocks.hsfs.metadata.TrainingDatasetApi; -import com.logicalclocks.hsfs.spark.constructor.Query; -import com.logicalclocks.hsfs.spark.engine.FeatureViewEngine; -import com.logicalclocks.hsfs.spark.engine.FeatureGroupEngine; -import com.logicalclocks.hsfs.spark.engine.SparkEngine; - import lombok.NonNull; import org.apache.spark.sql.Dataset; @@ -102,8 +101,8 @@ public FeatureGroup getFeatureGroup(@NonNull String name, @NonNull Integer versi */ public FeatureGroup getFeatureGroup(String name) throws FeatureStoreException, IOException { LOGGER.info("VersionWarning: No version provided for getting feature group `" + name + "`, defaulting to `" - + DEFAULT_VERSION + "`."); - return getFeatureGroup(name, DEFAULT_VERSION); + + FeatureStoreBase.DEFAULT_VERSION + "`."); + return getFeatureGroup(name, FeatureStoreBase.DEFAULT_VERSION); } /** @@ -326,8 +325,8 @@ public FeatureGroup getOrCreateFeatureGroup(String name, Integer version, String @Override public StreamFeatureGroup getStreamFeatureGroup(String name) throws FeatureStoreException, IOException { LOGGER.info("VersionWarning: No version provided for getting feature group `" + name + "`, defaulting to `" - + DEFAULT_VERSION + "`."); - return getStreamFeatureGroup(name, DEFAULT_VERSION); + + FeatureStoreBase.DEFAULT_VERSION + "`."); + return getStreamFeatureGroup(name, FeatureStoreBase.DEFAULT_VERSION); } /** @@ -625,8 +624,8 @@ public ExternalFeatureGroup getExternalFeatureGroup(@NonNull String name, @NonNu @Override public ExternalFeatureGroup getExternalFeatureGroup(String name) throws FeatureStoreException, IOException { LOGGER.info("VersionWarning: No version provided for getting feature group `" + name + "`, defaulting to `" - + DEFAULT_VERSION + "`."); - return getExternalFeatureGroup(name, DEFAULT_VERSION); + + FeatureStoreBase.DEFAULT_VERSION + "`."); + return getExternalFeatureGroup(name, FeatureStoreBase.DEFAULT_VERSION); } /** @@ -881,8 +880,8 @@ public ExternalFeatureGroup getOnDemandFeatureGroup(@NonNull String name, @NonNu @Deprecated public ExternalFeatureGroup getOnDemandFeatureGroup(String name) throws FeatureStoreException, IOException { LOGGER.info("VersionWarning: No version provided for getting feature group `" + name + "`, defaulting to `" - + DEFAULT_VERSION + "`."); - return getExternalFeatureGroup(name, DEFAULT_VERSION); + + FeatureStoreBase.DEFAULT_VERSION + "`."); + return getExternalFeatureGroup(name, FeatureStoreBase.DEFAULT_VERSION); } @Deprecated @@ -992,8 +991,8 @@ public FeatureView getFeatureView(@NonNull String name, @NonNull Integer version @Override public FeatureView getFeatureView(String name) throws FeatureStoreException, IOException { LOGGER.info("VersionWarning: No version provided for getting feature view `" + name + "`, defaulting to `" - + DEFAULT_VERSION + "`."); - return getFeatureView(name, DEFAULT_VERSION); + + FeatureStoreBase.DEFAULT_VERSION + "`."); + return getFeatureView(name, FeatureStoreBase.DEFAULT_VERSION); } @Override @@ -1016,8 +1015,8 @@ public TrainingDataset getTrainingDataset(@NonNull String name, @NonNull Integer @Deprecated public TrainingDataset getTrainingDataset(String name) throws FeatureStoreException, IOException { LOGGER.info("VersionWarning: No version provided for getting training dataset `" + name + "`, defaulting to `" - + DEFAULT_VERSION + "`."); - return getTrainingDataset(name, DEFAULT_VERSION); + + FeatureStoreBase.DEFAULT_VERSION + "`."); + return getTrainingDataset(name, FeatureStoreBase.DEFAULT_VERSION); } @Deprecated diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/FeatureView.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/FeatureView.java similarity index 99% rename from java/src/main/java/com/logicalclocks/hsfs/spark/FeatureView.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/FeatureView.java index 3e9f8c7aba..b7f0d1043e 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/FeatureView.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/FeatureView.java @@ -20,6 +20,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.logicalclocks.hsfs.spark.constructor.Query; +import com.logicalclocks.hsfs.spark.engine.FeatureViewEngine; import com.logicalclocks.hsfs.DataFormat; import com.logicalclocks.hsfs.FeatureStoreException; import com.logicalclocks.hsfs.FeatureViewBase; @@ -30,8 +32,6 @@ import com.logicalclocks.hsfs.constructor.Filter; import com.logicalclocks.hsfs.constructor.FilterLogic; import com.logicalclocks.hsfs.engine.FeatureGroupUtils; -import com.logicalclocks.hsfs.spark.constructor.Query; -import com.logicalclocks.hsfs.spark.engine.FeatureViewEngine; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -90,7 +90,7 @@ public FeatureViewBuilder description(String description) { public FeatureViewBuilder query(Query query) { this.query = query; if (query.isTimeTravel()) { - LOGGER.info("`as_of` argument in the `Query` will be ignored because " + FeatureViewBase.LOGGER.info("`as_of` argument in the `Query` will be ignored because " + "feature view does not support time travel query."); } return this; @@ -137,7 +137,7 @@ public FeatureView(@NonNull String name, Integer version, @NonNull Query query, */ @Override public void delete() throws FeatureStoreException, IOException { - LOGGER.warn("JobWarning: All jobs associated to feature view `" + name + "`, version `" + FeatureViewBase.LOGGER.warn("JobWarning: All jobs associated to feature view `" + name + "`, version `" + version + "` will be removed."); featureViewEngine.delete(this.featureStore, this.name, this.version); } diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/HopsworksConnection.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/HopsworksConnection.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/HopsworksConnection.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/HopsworksConnection.java index 674dba1982..e3b63a427f 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/HopsworksConnection.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/HopsworksConnection.java @@ -17,6 +17,7 @@ package com.logicalclocks.hsfs.spark; +import com.logicalclocks.hsfs.spark.engine.SparkEngine; import com.logicalclocks.hsfs.FeatureStoreException; import com.logicalclocks.hsfs.HopsworksConnectionBase; import com.logicalclocks.hsfs.SecretStore; @@ -24,7 +25,6 @@ import com.logicalclocks.hsfs.metadata.HopsworksHttpClient; import com.logicalclocks.hsfs.metadata.HopsworksInternalClient; -import com.logicalclocks.hsfs.spark.engine.SparkEngine; import lombok.Builder; import software.amazon.awssdk.regions.Region; diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/MainClass.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/MainClass.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/MainClass.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/MainClass.java index c4503d33f9..c9ff950a37 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/MainClass.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/MainClass.java @@ -17,10 +17,10 @@ package com.logicalclocks.hsfs.spark; +import com.logicalclocks.hsfs.spark.constructor.Query; +import com.logicalclocks.hsfs.spark.engine.SparkEngine; import com.logicalclocks.hsfs.DataFormat; import com.logicalclocks.hsfs.Split; -import com.logicalclocks.hsfs.spark.engine.SparkEngine; -import com.logicalclocks.hsfs.spark.constructor.Query; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/StreamFeatureGroup.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/StreamFeatureGroup.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/StreamFeatureGroup.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/StreamFeatureGroup.java index 06a5e3e4af..2008bb1856 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/StreamFeatureGroup.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/StreamFeatureGroup.java @@ -19,6 +19,9 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.logicalclocks.hsfs.spark.constructor.Query; +import com.logicalclocks.hsfs.spark.engine.FeatureGroupEngine; +import com.logicalclocks.hsfs.spark.engine.StatisticsEngine; import com.logicalclocks.hsfs.EntityEndpointType; import com.logicalclocks.hsfs.Feature; import com.logicalclocks.hsfs.FeatureStoreException; @@ -29,9 +32,6 @@ import com.logicalclocks.hsfs.engine.CodeEngine; import com.logicalclocks.hsfs.FeatureGroupBase; import com.logicalclocks.hsfs.metadata.Statistics; -import com.logicalclocks.hsfs.spark.constructor.Query; -import com.logicalclocks.hsfs.spark.engine.FeatureGroupEngine; -import com.logicalclocks.hsfs.spark.engine.StatisticsEngine; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/TrainingDataset.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/TrainingDataset.java similarity index 99% rename from java/src/main/java/com/logicalclocks/hsfs/spark/TrainingDataset.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/TrainingDataset.java index 4758b8eb57..e269c60425 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/TrainingDataset.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/TrainingDataset.java @@ -21,6 +21,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Strings; import com.google.common.collect.Lists; +import com.logicalclocks.hsfs.spark.constructor.Query; +import com.logicalclocks.hsfs.spark.engine.StatisticsEngine; +import com.logicalclocks.hsfs.spark.engine.TrainingDatasetEngine; import com.logicalclocks.hsfs.DataFormat; import com.logicalclocks.hsfs.EntityEndpointType; import com.logicalclocks.hsfs.FeatureStoreException; @@ -36,9 +39,6 @@ import com.logicalclocks.hsfs.engine.CodeEngine; import com.logicalclocks.hsfs.engine.FeatureGroupUtils; import com.logicalclocks.hsfs.metadata.Statistics; -import com.logicalclocks.hsfs.spark.constructor.Query; -import com.logicalclocks.hsfs.spark.engine.StatisticsEngine; -import com.logicalclocks.hsfs.spark.engine.TrainingDatasetEngine; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -339,7 +339,7 @@ public List getServingVector(Map entry) throws SQLExcept */ @Override public void delete() throws FeatureStoreException, IOException { - LOGGER.warn("JobWarning: All jobs associated to training dataset `" + name + "`, version `" + TrainingDatasetBase.LOGGER.warn("JobWarning: All jobs associated to training dataset `" + name + "`, version `" + version + "` will be removed."); trainingDatasetEngine.delete(this); } diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/TrainingDatasetBundle.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/TrainingDatasetBundle.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/TrainingDatasetBundle.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/TrainingDatasetBundle.java index 664c0252a5..c63c7f343a 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/TrainingDatasetBundle.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/TrainingDatasetBundle.java @@ -19,8 +19,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.google.common.collect.Lists; -import com.logicalclocks.hsfs.Split; import com.logicalclocks.hsfs.spark.engine.SparkEngine; +import com.logicalclocks.hsfs.Split; import lombok.Getter; import org.apache.spark.sql.Dataset; import org.apache.spark.sql.Row; diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/constructor/FsQuery.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/constructor/FsQuery.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/constructor/FsQuery.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/constructor/FsQuery.java index 72b52126ae..569e3db632 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/constructor/FsQuery.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/constructor/FsQuery.java @@ -18,12 +18,12 @@ package com.logicalclocks.hsfs.spark.constructor; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.logicalclocks.hsfs.spark.engine.SparkEngine; import com.logicalclocks.hsfs.FeatureStoreException; import com.logicalclocks.hsfs.constructor.FeatureGroupAlias; import com.logicalclocks.hsfs.constructor.FsQueryBase; import com.logicalclocks.hsfs.spark.ExternalFeatureGroup; import com.logicalclocks.hsfs.spark.StreamFeatureGroup; -import com.logicalclocks.hsfs.spark.engine.SparkEngine; import lombok.AllArgsConstructor; import java.io.IOException; diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/constructor/Query.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/constructor/Query.java similarity index 94% rename from java/src/main/java/com/logicalclocks/hsfs/spark/constructor/Query.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/constructor/Query.java index 43429b69a9..8f533e39db 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/constructor/Query.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/constructor/Query.java @@ -71,7 +71,7 @@ public Dataset read(boolean online, Map readOptions) throws queryConstructorApi.constructQuery(leftFeatureGroup.getFeatureStore(), this, FsQuery.class); if (online) { - LOGGER.info("Executing query: " + fsQuery.getStorageQuery(Storage.ONLINE)); + QueryBase.LOGGER.info("Executing query: " + fsQuery.getStorageQuery(Storage.ONLINE)); StorageConnector.JdbcConnector onlineConnector = storageConnectorApi.getOnlineStorageConnector( leftFeatureGroup.getFeatureStore(), StorageConnector.JdbcConnector.class); @@ -80,7 +80,7 @@ public Dataset read(boolean online, Map readOptions) throws fsQuery.registerOnDemandFeatureGroups(); fsQuery.registerHudiFeatureGroups(readOptions); - LOGGER.info("Executing query: " + fsQuery.getStorageQuery(Storage.OFFLINE)); + QueryBase.LOGGER.info("Executing query: " + fsQuery.getStorageQuery(Storage.OFFLINE)); return SparkEngine.getInstance().sql(fsQuery.getStorageQuery(Storage.OFFLINE)); } } diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/FeatureGroupEngine.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/FeatureGroupEngine.java similarity index 99% rename from java/src/main/java/com/logicalclocks/hsfs/spark/engine/FeatureGroupEngine.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/FeatureGroupEngine.java index 61024b68dc..22cc333389 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/FeatureGroupEngine.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/FeatureGroupEngine.java @@ -17,6 +17,7 @@ package com.logicalclocks.hsfs.spark.engine; +import com.logicalclocks.hsfs.spark.engine.hudi.HudiEngine; import com.logicalclocks.hsfs.Feature; import com.logicalclocks.hsfs.FeatureGroupCommit; import com.logicalclocks.hsfs.FeatureStoreException; @@ -32,7 +33,6 @@ import com.logicalclocks.hsfs.spark.FeatureGroup; import com.logicalclocks.hsfs.spark.FeatureStore; -import com.logicalclocks.hsfs.spark.engine.hudi.HudiEngine; import lombok.SneakyThrows; import org.apache.spark.sql.Dataset; @@ -235,7 +235,7 @@ public FeatureGroup saveFeatureGroupMetaData(FeatureGroup featureGroup, List onlineFeatureGroupToAvro(FeatureGroupBase featureGroupBase, return dataset.select( to_avro(concat(pks.stream().map(name -> col(name).cast("string")) .toArray(Column[]::new))).alias("key"), - to_avro(struct(featureGroupBase.getDeserializedAvroSchema().getFields().stream() + to_avro(functions.struct(featureGroupBase.getDeserializedAvroSchema().getFields().stream() .map(f -> col(f.name())).toArray(Column[]::new)), featureGroupBase.getEncodedAvroSchema()).alias("value")); } diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/StatisticsEngine.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/StatisticsEngine.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/engine/StatisticsEngine.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/StatisticsEngine.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetEngine.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetEngine.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetEngine.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetEngine.java index bc816062b4..f2799c8908 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetEngine.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetEngine.java @@ -18,6 +18,7 @@ package com.logicalclocks.hsfs.spark.engine; import com.google.common.collect.Maps; +import com.logicalclocks.hsfs.spark.constructor.Query; import com.logicalclocks.hsfs.EntityEndpointType; import com.logicalclocks.hsfs.FeatureStoreException; import com.logicalclocks.hsfs.Storage; @@ -25,7 +26,6 @@ import com.logicalclocks.hsfs.metadata.TagsApi; import com.logicalclocks.hsfs.metadata.TrainingDatasetApi; import com.logicalclocks.hsfs.spark.TrainingDataset; -import com.logicalclocks.hsfs.spark.constructor.Query; import com.logicalclocks.hsfs.spark.util.StorageConnectorUtils; import org.apache.hadoop.fs.Path; diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetUtils.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetUtils.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetUtils.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/TrainingDatasetUtils.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerAvroDeserializer.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerAvroDeserializer.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerAvroDeserializer.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerAvroDeserializer.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerConfig.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerConfig.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerConfig.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerConfig.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerKafkaSource.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerKafkaSource.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerKafkaSource.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerKafkaSource.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerSchemaProvider.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerSchemaProvider.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerSchemaProvider.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerSchemaProvider.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerTransformer.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerTransformer.java similarity index 100% rename from java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerTransformer.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/DeltaStreamerTransformer.java diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/HudiEngine.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/HudiEngine.java similarity index 97% rename from java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/HudiEngine.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/HudiEngine.java index b80f70a486..afddae7fb7 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/HudiEngine.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/engine/hudi/HudiEngine.java @@ -112,16 +112,16 @@ public class HudiEngine { protected static final String COMMIT_METADATA_KEYPREFIX_OPT_KEY = "hoodie.datasource.write.commitmeta.key.prefix"; protected static final String DELTASTREAMER_CHECKPOINT_KEY = "deltastreamer.checkpoint.key"; protected static final String INITIAL_CHECKPOINT_STRING = "initialCheckPointString"; - protected static final String FEATURE_GROUP_SCHEMA = "com.logicalclocks.hsfs.spark.StreamFeatureGroup.avroSchema"; + protected static final String FEATURE_GROUP_SCHEMA = "StreamFeatureGroup.avroSchema"; protected static final String FEATURE_GROUP_ENCODED_SCHEMA = - "com.logicalclocks.hsfs.spark.StreamFeatureGroup.encodedAvroSchema"; + "StreamFeatureGroup.encodedAvroSchema"; protected static final String FEATURE_GROUP_COMPLEX_FEATURES = - "com.logicalclocks.hsfs.spark.StreamFeatureGroup.complexFeatures"; - protected static final String KAFKA_SOURCE = "com.logicalclocks.hsfs.spark.engine.hudi.DeltaStreamerKafkaSource"; + "StreamFeatureGroup.complexFeatures"; + protected static final String KAFKA_SOURCE = "DeltaStreamerKafkaSource"; protected static final String SCHEMA_PROVIDER = - "com.logicalclocks.hsfs.spark.engine.hudi.DeltaStreamerSchemaProvider"; + "DeltaStreamerSchemaProvider"; protected static final String DELTA_STREAMER_TRANSFORMER = - "com.logicalclocks.hsfs.spark.engine.hudi.DeltaStreamerTransformer"; + "DeltaStreamerTransformer"; protected static final String DELTA_SOURCE_ORDERING_FIELD_OPT_KEY = "sourceOrderingField"; protected static final String MIN_SYNC_INTERVAL_SECONDS = "minSyncIntervalSeconds"; diff --git a/java/src/main/java/com/logicalclocks/hsfs/spark/util/StorageConnectorUtils.java b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/util/StorageConnectorUtils.java similarity index 97% rename from java/src/main/java/com/logicalclocks/hsfs/spark/util/StorageConnectorUtils.java rename to java/spark/src/main/java/com/logicalclocks/hsfs/spark/util/StorageConnectorUtils.java index 3bd3c130b4..2c40fbccad 100644 --- a/java/src/main/java/com/logicalclocks/hsfs/spark/util/StorageConnectorUtils.java +++ b/java/spark/src/main/java/com/logicalclocks/hsfs/spark/util/StorageConnectorUtils.java @@ -18,16 +18,19 @@ package com.logicalclocks.hsfs.spark.util; import com.google.common.base.Strings; +import com.logicalclocks.hsfs.spark.engine.SparkEngine; import com.logicalclocks.hsfs.FeatureStoreException; import com.logicalclocks.hsfs.StorageConnector; import com.logicalclocks.hsfs.util.Constants; -import com.logicalclocks.hsfs.spark.engine.SparkEngine; import org.apache.spark.sql.Dataset; import org.apache.spark.sql.Row; import javax.ws.rs.NotSupportedException; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; +import java.util.Base64; import java.util.Map; public class StorageConnectorUtils { @@ -173,6 +176,12 @@ public Dataset read(StorageConnector.BigqueryConnector connector, String qu Map options, String path) throws FeatureStoreException, IOException { Map readOptions = connector.sparkOptions(); + + // Base64 encode the credentials file + String localKeyPath = SparkEngine.getInstance().addFile(connector.getKeyPath()); + byte[] fileContent = Files.readAllBytes(Paths.get(localKeyPath)); + options.put(Constants.BIGQ_CREDENTIALS, Base64.getEncoder().encodeToString(fileContent)); + // merge user spark options on top of default spark options if (options != null && !options.isEmpty()) { readOptions.putAll(options); diff --git a/java/src/test/java/com/logicalclocks/hsfs/spark/TestExternalFeatureGroup.java b/java/spark/src/test/java/com/logicalclocks/hsfs/spark/TestExternalFeatureGroup.java similarity index 100% rename from java/src/test/java/com/logicalclocks/hsfs/spark/TestExternalFeatureGroup.java rename to java/spark/src/test/java/com/logicalclocks/hsfs/spark/TestExternalFeatureGroup.java diff --git a/java/src/test/java/com/logicalclocks/hsfs/spark/TestFeature.java b/java/spark/src/test/java/com/logicalclocks/hsfs/spark/TestFeature.java similarity index 100% rename from java/src/test/java/com/logicalclocks/hsfs/spark/TestFeature.java rename to java/spark/src/test/java/com/logicalclocks/hsfs/spark/TestFeature.java diff --git a/java/src/test/java/com/logicalclocks/hsfs/spark/TestFeatureGroup.java b/java/spark/src/test/java/com/logicalclocks/hsfs/spark/TestFeatureGroup.java similarity index 100% rename from java/src/test/java/com/logicalclocks/hsfs/spark/TestFeatureGroup.java rename to java/spark/src/test/java/com/logicalclocks/hsfs/spark/TestFeatureGroup.java diff --git a/java/src/test/java/com/logicalclocks/TestStorageConnector.java b/java/spark/src/test/java/com/logicalclocks/hsfs/spark/TestStorageConnector.java similarity index 94% rename from java/src/test/java/com/logicalclocks/TestStorageConnector.java rename to java/spark/src/test/java/com/logicalclocks/hsfs/spark/TestStorageConnector.java index ceb74bb294..5ebed968c2 100644 --- a/java/src/test/java/com/logicalclocks/TestStorageConnector.java +++ b/java/spark/src/test/java/com/logicalclocks/hsfs/spark/TestStorageConnector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2022. Hopsworks AB + * Copyright (c) 2022-2023. Hopsworks AB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ * */ -package com.logicalclocks; +package com.logicalclocks.hsfs.spark; import com.logicalclocks.hsfs.FeatureStoreException; import com.logicalclocks.hsfs.StorageConnectorType; @@ -39,6 +39,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Base64; import java.util.Map; @@ -57,12 +58,15 @@ public void testBigQueryCredentialsBase64Encoded(@TempDir Path tempDir) throws I } else { bigqueryConnector.setKeyPath("file://" + credentialsFile); } + // Act - Map sparkOptions = bigqueryConnector.sparkOptions(); + // Base64 encode the credentials file + String localKeyPath = SparkEngine.getInstance().addFile(bigqueryConnector.getKeyPath()); + String fileContent = Base64.getEncoder().encodeToString(Files.readAllBytes(Paths.get(localKeyPath))); // Assert Assertions.assertEquals(credentials, - new String(Base64.getDecoder().decode(sparkOptions.get(Constants.BIGQ_CREDENTIALS)), StandardCharsets.UTF_8)); + new String(Base64.getDecoder().decode(fileContent), StandardCharsets.UTF_8)); } @Test @@ -104,6 +108,7 @@ public void testGcsConnectorCredentials(@TempDir Path tempDir) throws IOExceptio gcsConnector.setKeyPath("file://" + credentialsFile); } gcsConnector.setStorageConnectorType(StorageConnectorType.GCS); + // Act SparkEngine.getInstance().setupConnectorHadoopConf(gcsConnector); SparkContext sc = SparkEngine.getInstance().getSparkSession().sparkContext(); @@ -141,6 +146,7 @@ public void testGcsConnectorCredentials_encrypted(@TempDir Path tempDir) throws gcsConnector.setAlgorithm("AES256"); gcsConnector.setEncryptionKey("encryptionkey"); gcsConnector.setEncryptionKeyHash("encryptionkeyhash"); + // Act SparkEngine.getInstance().setupConnectorHadoopConf(gcsConnector); SparkContext sc = SparkEngine.getInstance().getSparkSession().sparkContext(); diff --git a/java/src/test/java/com/logicalclocks/hsfs/spark/engine/TestFeatureViewEngine.java b/java/spark/src/test/java/com/logicalclocks/hsfs/spark/engine/TestFeatureViewEngine.java similarity index 100% rename from java/src/test/java/com/logicalclocks/hsfs/spark/engine/TestFeatureViewEngine.java rename to java/spark/src/test/java/com/logicalclocks/hsfs/spark/engine/TestFeatureViewEngine.java diff --git a/java/src/test/java/com/logicalclocks/hsfs/spark/engine/TestHudiEngine.java b/java/spark/src/test/java/com/logicalclocks/hsfs/spark/engine/TestHudiEngine.java similarity index 100% rename from java/src/test/java/com/logicalclocks/hsfs/spark/engine/TestHudiEngine.java rename to java/spark/src/test/java/com/logicalclocks/hsfs/spark/engine/TestHudiEngine.java diff --git a/java/src/test/java/com/logicalclocks/hsfs/spark/engine/TestSparkEngine.java b/java/spark/src/test/java/com/logicalclocks/hsfs/spark/engine/TestSparkEngine.java similarity index 100% rename from java/src/test/java/com/logicalclocks/hsfs/spark/engine/TestSparkEngine.java rename to java/spark/src/test/java/com/logicalclocks/hsfs/spark/engine/TestSparkEngine.java diff --git a/java/spark/src/test/resources/hadoop/bin/winutils.exe b/java/spark/src/test/resources/hadoop/bin/winutils.exe new file mode 100644 index 0000000000000000000000000000000000000000..aef881bc2a6aa31a0a3727e568053cda037f6bf4 GIT binary patch literal 112640 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 literal 0 HcmV?d00001 diff --git a/java/spark/src/test/resources/system.properties b/java/spark/src/test/resources/system.properties new file mode 100644 index 0000000000..3d39703a4f --- /dev/null +++ b/java/spark/src/test/resources/system.properties @@ -0,0 +1 @@ +spark.master=local[1]