diff --git a/.github/workflows/complete.yml b/.github/workflows/complete.yml
index 660304a8546..ebe0216a0f6 100644
--- a/.github/workflows/complete.yml
+++ b/.github/workflows/complete.yml
@@ -3,45 +3,6 @@ name: complete
on: [push, pull_request]
jobs:
- build-push-docker-images:
- runs-on: [self-hosted]
- strategy:
- matrix:
- component: [core, serving, jupyter, ci]
- env:
- GITHUB_PR_SHA: ${{ github.event.pull_request.head.sha }}
- REGISTRY: gcr.io/kf-feast
- MAVEN_CACHE: gs://feast-templocation-kf-feast/.m2.2020-08-19.tar
- steps:
- - uses: actions/checkout@v2
- - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
- with:
- version: '290.0.1'
- export_default_credentials: true
- - run: gcloud auth configure-docker --quiet
- - name: Get m2 cache
- run: |
- infra/scripts/download-maven-cache.sh \
- --archive-uri ${MAVEN_CACHE} \
- --output-dir .
- - name: Build image
- run: make build-${{ matrix.component }}-docker REGISTRY=${REGISTRY} VERSION=${GITHUB_SHA}
- - name: Push image
- run: |
- docker push ${REGISTRY}/feast-${{ matrix.component }}:${GITHUB_SHA}
- if [ -n "${GITHUB_PR_SHA}" ]; then
- docker tag ${REGISTRY}/feast-${{ matrix.component }}:${GITHUB_SHA} gcr.io/kf-feast/feast-${{ matrix.component }}:${GITHUB_PR_SHA}
- docker push ${REGISTRY}/feast-${{ matrix.component }}:${GITHUB_PR_SHA}
- fi
-
- lint-java:
- container: gcr.io/kf-feast/feast-ci:latest
- runs-on: [ubuntu-latest]
- steps:
- - uses: actions/checkout@v2
- - name: Lint java
- run: make lint-java
-
lint-python:
container: gcr.io/kf-feast/feast-ci:latest
runs-on: [ubuntu-latest]
@@ -64,37 +25,6 @@ jobs:
- name: Lint go
run: make lint-go
- lint-versions:
- runs-on: [ubuntu-latest]
- steps:
- - uses: actions/checkout@v2
- - name: Lint versions throughout repo
- run: make lint-versions
-
- unit-test-java:
- runs-on: ubuntu-latest
- needs: lint-java
- steps:
- - uses: actions/checkout@v2
- - name: Set up JDK 11
- uses: actions/setup-java@v1
- with:
- java-version: '11'
- java-package: jdk
- architecture: x64
- - uses: actions/cache@v2
- with:
- path: ~/.m2/repository
- key: ${{ runner.os }}-ut-maven-${{ hashFiles('**/pom.xml') }}
- restore-keys: |
- ${{ runner.os }}-ut-maven-
- - name: Test java
- run: make test-java-with-coverage
- - uses: actions/upload-artifact@v2
- with:
- name: java-coverage-report
- path: ${{ github.workspace }}/docs/coverage/java/target/site/jacoco-aggregate/
-
unit-test-python:
runs-on: ubuntu-latest
needs: lint-python
@@ -117,33 +47,3 @@ jobs:
- name: Test go
run: make test-go
- integration-test:
- runs-on: ubuntu-latest
- needs: unit-test-java
- steps:
- - uses: actions/checkout@v2
- - name: Set up JDK 11
- uses: actions/setup-java@v1
- with:
- java-version: '11'
- java-package: jdk
- architecture: x64
- - uses: actions/setup-python@v2
- with:
- python-version: '3.6'
- architecture: 'x64'
- - uses: actions/cache@v2
- with:
- path: ~/.m2/repository
- key: ${{ runner.os }}-it-maven-${{ hashFiles('**/pom.xml') }}
- restore-keys: |
- ${{ runner.os }}-it-maven-
- - name: Run integration tests
- run: make test-java-integration
- - name: Save report
- uses: actions/upload-artifact@v2
- if: failure()
- with:
- name: it-report
- path: spark/ingestion/target/test-reports/TestSuite.txt
- retention-days: 5
diff --git a/.github/workflows/master_only.yml b/.github/workflows/master_only.yml
deleted file mode 100644
index dadc1c27f9d..00000000000
--- a/.github/workflows/master_only.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: master only
-
-on:
- push:
- branches: master
- tags:
- - 'v*.*.*'
-
-jobs:
- build-docker-images:
- runs-on: [self-hosted]
- strategy:
- matrix:
- component: [core, serving, jupyter, ci]
- env:
- MAVEN_CACHE: gs://feast-templocation-kf-feast/.m2.2020-08-19.tar
- steps:
- - uses: actions/checkout@v2
- - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
- with:
- version: '290.0.1'
- export_default_credentials: true
- - run: gcloud auth configure-docker --quiet
- - name: Get m2 cache
- run: |
- infra/scripts/download-maven-cache.sh \
- --archive-uri ${MAVEN_CACHE} \
- --output-dir .
- - name: Get version
- run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- - name: Build image
- run: make build-${{ matrix.component }}-docker REGISTRY=gcr.io/kf-feast VERSION=${GITHUB_SHA}
- - name: Push image
- run: make push-${{ matrix.component }}-docker REGISTRY=gcr.io/kf-feast VERSION=${GITHUB_SHA}
- - name: Push development Docker image
- run: |
- if [ ${GITHUB_REF#refs/*/} == "master" ]; then
- docker tag gcr.io/kf-feast/feast-${{ matrix.component }}:${GITHUB_SHA} gcr.io/kf-feast/feast-${{ matrix.component }}:develop
- docker push gcr.io/kf-feast/feast-${{ matrix.component }}:develop
- fi
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 157a593d35f..1622995f1b6 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -48,7 +48,7 @@ jobs:
needs: get-version
strategy:
matrix:
- component: [core, serving, jobservice, jupyter]
+ component: [jobservice, jupyter]
env:
MAVEN_CACHE: gs://feast-templocation-kf-feast/.m2.2020-08-19.tar
steps:
@@ -111,8 +111,6 @@ jobs:
project_id: ${{ secrets.GCP_PROJECT_ID }}
service_account_key: ${{ secrets.GCP_SA_KEY }}
- run: gcloud auth configure-docker --quiet
- - name: Validate repository versions
- run: make lint-versions
- name: Validate chart release versions
run: ./infra/scripts/validate-helm-chart-docker-image.sh
- name: Remove previous Helm
@@ -120,4 +118,4 @@ jobs:
- name: Install Helm
run: ./infra/scripts/install-helm.sh
- name: Publish Helm charts
- run: ./infra/scripts/sync-helm-charts.sh
\ No newline at end of file
+ run: ./infra/scripts/sync-helm-charts.sh
diff --git a/.scalafmt.conf b/.scalafmt.conf
deleted file mode 100644
index f3c72b8ceb5..00000000000
--- a/.scalafmt.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-align.preset = more
-maxColumn = 100
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 89b9433bfa6..9b55c9d1111 100644
--- a/Makefile
+++ b/Makefile
@@ -17,47 +17,20 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
PROTO_TYPE_SUBDIRS = core serving types storage
PROTO_SERVICE_SUBDIRS = core serving
-MVN := mvn ${MAVEN_EXTRA_OPTS}
# General
-format: format-python format-go format-java
+format: format-python format-go
-lint: lint-python lint-go lint-java
+lint: lint-python lint-go
-test: test-python test-java test-go
+test: test-python test-go
protos: compile-protos-go compile-protos-python compile-protos-docs
-build: protos build-java build-docker build-html
+build: protos build-docker build-html
-install-ci-dependencies: install-python-ci-dependencies install-go-ci-dependencies install-java-ci-dependencies
-
-# Java
-
-install-java-ci-dependencies:
- ${MVN} verify clean --fail-never
-
-format-java:
- ${MVN} spotless:apply
-
-lint-java:
- ${MVN} --no-transfer-progress spotless:check
-
-test-java:
- ${MVN} --no-transfer-progress -DskipITs=true test
-
-test-java-integration:
- ${MVN} --no-transfer-progress -Dmaven.javadoc.skip=true -Dgpg.skip -DskipUTs=true clean verify
-
-test-java-with-coverage:
- ${MVN} --no-transfer-progress -DskipITs=true test jacoco:report-aggregate
-
-build-java:
- ${MVN} clean verify
-
-build-java-no-tests:
- ${MVN} --no-transfer-progress -Dmaven.javadoc.skip=true -Dgpg.skip -DskipUTs=true -DskipITs=true -Drevision=${REVISION} clean package
+install-ci-dependencies: install-python-ci-dependencies install-go-ci-dependencies
# Python SDK
@@ -112,17 +85,9 @@ lint-go:
build-push-docker:
@$(MAKE) build-docker registry=$(REGISTRY) version=$(VERSION)
- @$(MAKE) push-core-docker registry=$(REGISTRY) version=$(VERSION)
- @$(MAKE) push-serving-docker registry=$(REGISTRY) version=$(VERSION)
@$(MAKE) push-ci-docker registry=$(REGISTRY) version=$(VERSION)
-build-docker: build-core-docker build-serving-docker build-ci-docker
-
-push-core-docker:
- docker push $(REGISTRY)/feast-core:$(VERSION)
-
-push-serving-docker:
- docker push $(REGISTRY)/feast-serving:$(VERSION)
+build-docker: build-ci-docker
push-ci-docker:
docker push $(REGISTRY)/feast-ci:$(VERSION)
@@ -130,12 +95,6 @@ push-ci-docker:
push-jupyter-docker:
docker push $(REGISTRY)/feast-jupyter:$(VERSION)
-build-core-docker:
- docker build --build-arg VERSION=$(VERSION) -t $(REGISTRY)/feast-core:$(VERSION) -f infra/docker/core/Dockerfile .
-
-build-serving-docker:
- docker build --build-arg VERSION=$(VERSION) -t $(REGISTRY)/feast-serving:$(VERSION) -f infra/docker/serving/Dockerfile .
-
build-ci-docker:
docker build -t $(REGISTRY)/feast-ci:$(VERSION) -f infra/docker/ci/Dockerfile .
@@ -183,11 +142,6 @@ build-html: clean-html
cd $(ROOT_DIR)/sdk/python/docs && $(MAKE) html
cp -r $(ROOT_DIR)/sdk/python/docs/html/* $(ROOT_DIR)/dist/python
-# Versions
-
-lint-versions:
- ./infra/scripts/validate-version-consistency.sh
-
# Performance
test-load:
diff --git a/common-test/pom.xml b/common-test/pom.xml
deleted file mode 100644
index 0232b4dc7f1..00000000000
--- a/common-test/pom.xml
+++ /dev/null
@@ -1,172 +0,0 @@
-
-
-
- 4.0.0
-
-
- feast-parent
- dev.feast
- ${revision}
-
-
- Feast Common Test
- Feast common module with test utilities
- feast-common-test
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 3.0.0-M4
-
- -Xms2048m -Xmx2048m -Djdk.net.URLClassPath.disableClassPathURLCheck=true
-
-
-
-
-
-
-
- dev.feast
- datatypes-java
- ${project.version}
- compile
-
-
- dev.feast
- feast-common
- ${project.version}
- compile
-
-
- com.google.protobuf
- protobuf-java-util
-
-
-
- org.projectlombok
- lombok
- ${lombok.version}
-
-
- javax.validation
- validation-api
-
-
- com.google.auto.value
- auto-value-annotations
-
-
- com.google.code.gson
- gson
-
-
-
-
- org.slf4j
- slf4j-api
-
-
-
- org.hamcrest
- hamcrest-library
-
-
- org.springframework.boot
- spring-boot-test
- ${spring.boot.version}
-
-
- org.springframework.boot
- spring-boot-test-autoconfigure
-
-
- org.springframework
- spring-test
- ${spring.version}
-
-
- org.testcontainers
- junit-jupiter
- 1.15.1
-
-
- org.testcontainers
- postgresql
- 1.15.1
-
-
- org.testcontainers
- kafka
- 1.15.1
-
-
- org.junit.jupiter
- junit-jupiter-api
- 5.6.2
-
-
- org.springframework.kafka
- spring-kafka
-
-
- io.prometheus
- simpleclient
- 0.8.0
-
-
- org.apache.commons
- commons-lang3
- 3.4
-
-
- org.awaitility
- awaitility
- 3.0.0
-
-
- org.awaitility
- awaitility-proxy
- 3.0.0
-
-
- org.mockito
- mockito-core
- ${mockito.version}
- compile
-
-
- io.rest-assured
- rest-assured
- 4.2.0
-
-
- io.rest-assured
- json-path
- 4.2.0
-
-
- io.rest-assured
- xml-path
- 4.2.0
-
-
-
diff --git a/common-test/src/main/java/feast/common/it/BaseIT.java b/common-test/src/main/java/feast/common/it/BaseIT.java
deleted file mode 100644
index f82a804ee1c..00000000000
--- a/common-test/src/main/java/feast/common/it/BaseIT.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.it;
-
-import io.prometheus.client.CollectorRegistry;
-import java.sql.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.kafka.clients.consumer.ConsumerConfig;
-import org.apache.kafka.common.serialization.ByteArrayDeserializer;
-import org.apache.kafka.common.serialization.StringDeserializer;
-import org.junit.jupiter.api.*;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.context.annotation.Bean;
-import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
-import org.springframework.kafka.config.KafkaListenerContainerFactory;
-import org.springframework.kafka.core.ConsumerFactory;
-import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
-import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.DynamicPropertyRegistry;
-import org.springframework.test.context.DynamicPropertySource;
-import org.testcontainers.containers.KafkaContainer;
-import org.testcontainers.containers.PostgreSQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-
-/**
- * Base Integration Test class. Setups postgres and kafka containers. Configures related properties
- * and beans. Provides DB related clean up between tests.
- */
-@SpringBootTest
-@ActiveProfiles("it")
-@Testcontainers
-@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-public class BaseIT {
-
- @Container public static PostgreSQLContainer> postgreSQLContainer = new PostgreSQLContainer<>();
-
- @Container public static KafkaContainer kafka = new KafkaContainer();
-
- /**
- * Configure Spring Application to use postgres and kafka rolled out in containers
- *
- * @param registry
- */
- @DynamicPropertySource
- static void properties(DynamicPropertyRegistry registry) {
-
- registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl);
- registry.add("spring.datasource.username", postgreSQLContainer::getUsername);
- registry.add("spring.datasource.password", postgreSQLContainer::getPassword);
- registry.add("spring.jpa.hibernate.ddl-auto", () -> "none");
-
- registry.add("feast.stream.options.bootstrapServers", kafka::getBootstrapServers);
- }
-
- /**
- * SequentialFlow is base class that is supposed to be inherited by @Nested test classes that
- * wants to preserve context between test cases. For SequentialFlow databases is being truncated
- * only once after all tests passed.
- */
- @TestInstance(TestInstance.Lifecycle.PER_CLASS)
- public class SequentialFlow {
- @AfterAll
- public void tearDown() throws Exception {
- cleanTables();
- }
- }
-
- /**
- * This class must be inherited inside IT Class and annotated with {@link
- * org.springframework.boot.test.context.TestConfiguration}. It provides configuration needed to
- * communicate with Feast via Kafka
- */
- public static class BaseTestConfig {
- @Bean
- public KafkaListenerContainerFactory>
- testListenerContainerFactory(ConsumerFactory consumerFactory) {
- ConcurrentKafkaListenerContainerFactory factory =
- new ConcurrentKafkaListenerContainerFactory<>();
- factory.setConsumerFactory(consumerFactory);
- return factory;
- }
-
- @Bean
- public ConsumerFactory testConsumerFactory() {
- Map props = new HashMap<>();
-
- props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers());
- props.put(ConsumerConfig.GROUP_ID_CONFIG, this.getClass().getName());
-
- return new DefaultKafkaConsumerFactory<>(
- props, new StringDeserializer(), new ByteArrayDeserializer());
- }
- }
-
- /**
- * Truncates all tables in Database (between tests or flows). Retries on deadlock
- *
- * @throws SQLException
- */
- public static void cleanTables() throws SQLException {
- Connection connection =
- DriverManager.getConnection(
- postgreSQLContainer.getJdbcUrl(),
- postgreSQLContainer.getUsername(),
- postgreSQLContainer.getPassword());
-
- List tableNames = new ArrayList<>();
- Statement statement = connection.createStatement();
- ResultSet rs =
- statement.executeQuery(
- "SELECT table_name FROM information_schema.tables WHERE table_schema='public'");
- while (rs.next()) {
- tableNames.add(rs.getString(1));
- }
-
- if (tableNames.isEmpty()) {
- return;
- }
-
- // retries are needed since truncate require exclusive lock
- // and that often leads to Deadlock
- // since SpringApp is still running in another thread
- int num_retries = 5;
- for (int i = 1; i <= num_retries; i++) {
- try {
- statement = connection.createStatement();
- statement.execute(String.format("truncate %s cascade", String.join(", ", tableNames)));
- } catch (SQLException e) {
- if (i == num_retries) {
- throw e;
- }
- continue;
- }
-
- break;
- }
- }
-
- /** Used to determine SequentialFlows */
- public Boolean isSequentialTest(TestInfo testInfo) {
- try {
- testInfo.getTestClass().get().asSubclass(SequentialFlow.class);
- } catch (ClassCastException e) {
- return false;
- }
- return true;
- }
-
- @AfterEach
- public void tearDown(TestInfo testInfo) throws Exception {
- CollectorRegistry.defaultRegistry.clear();
-
- if (!isSequentialTest(testInfo)) {
- cleanTables();
- }
- }
-}
diff --git a/common-test/src/main/java/feast/common/it/DataGenerator.java b/common-test/src/main/java/feast/common/it/DataGenerator.java
deleted file mode 100644
index 0606c759516..00000000000
--- a/common-test/src/main/java/feast/common/it/DataGenerator.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.it;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.protobuf.Duration;
-import com.google.protobuf.Timestamp;
-import feast.proto.core.DataFormatProto.FileFormat;
-import feast.proto.core.DataFormatProto.FileFormat.ParquetFormat;
-import feast.proto.core.DataFormatProto.StreamFormat;
-import feast.proto.core.DataFormatProto.StreamFormat.AvroFormat;
-import feast.proto.core.DataFormatProto.StreamFormat.ProtoFormat;
-import feast.proto.core.DataSourceProto.DataSource;
-import feast.proto.core.DataSourceProto.DataSource.FileOptions;
-import feast.proto.core.DataSourceProto.DataSource.KafkaOptions;
-import feast.proto.core.DataSourceProto.DataSource.KinesisOptions;
-import feast.proto.core.EntityProto;
-import feast.proto.core.FeatureProto;
-import feast.proto.core.FeatureProto.FeatureSpecV2;
-import feast.proto.core.FeatureTableProto.FeatureTableSpec;
-import feast.proto.core.StoreProto;
-import feast.proto.serving.ServingAPIProto;
-import feast.proto.types.ValueProto;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import org.apache.commons.lang3.tuple.Triple;
-
-public class DataGenerator {
- // projectName, featureName, exclude
- static Triple defaultSubscription = Triple.of("*", "*", false);
-
- static StoreProto.Store defaultStore =
- createStore(
- "test-store", StoreProto.Store.StoreType.REDIS, ImmutableList.of(defaultSubscription));
-
- public static Triple getDefaultSubscription() {
- return defaultSubscription;
- }
-
- public static StoreProto.Store getDefaultStore() {
- return defaultStore;
- }
-
- public static StoreProto.Store createStore(
- String name,
- StoreProto.Store.StoreType type,
- List> subscriptions) {
- StoreProto.Store.Builder builder =
- StoreProto.Store.newBuilder()
- .addAllSubscriptions(
- subscriptions.stream()
- .map(
- s ->
- StoreProto.Store.Subscription.newBuilder()
- .setProject(s.getLeft())
- .setName(s.getMiddle())
- .setExclude(s.getRight())
- .build())
- .collect(Collectors.toList()))
- .setName(name)
- .setType(type);
-
- switch (type) {
- case REDIS:
- StoreProto.Store.RedisConfig redisConfig =
- StoreProto.Store.RedisConfig.newBuilder().build();
- return builder.setRedisConfig(redisConfig).build();
- case REDIS_CLUSTER:
- StoreProto.Store.RedisClusterConfig redisClusterConfig =
- StoreProto.Store.RedisClusterConfig.newBuilder().build();
- return builder.setRedisClusterConfig(redisClusterConfig).build();
- default:
- throw new RuntimeException("Unrecognized Store type");
- }
- }
-
- public static EntityProto.EntitySpecV2 createEntitySpecV2(
- String name,
- String description,
- ValueProto.ValueType.Enum valueType,
- Map labels) {
- return EntityProto.EntitySpecV2.newBuilder()
- .setName(name)
- .setDescription(description)
- .setValueType(valueType)
- .putAllLabels(labels)
- .build();
- }
-
- public static FeatureProto.FeatureSpecV2 createFeatureSpecV2(
- String name, ValueProto.ValueType.Enum valueType, Map labels) {
- return FeatureProto.FeatureSpecV2.newBuilder()
- .setName(name)
- .setValueType(valueType)
- .putAllLabels(labels)
- .build();
- }
-
- // Create a Feature Table spec without DataSources configured.
- public static FeatureTableSpec createFeatureTableSpec(
- String name,
- List entities,
- Map features,
- int maxAgeSecs,
- Map labels) {
-
- return FeatureTableSpec.newBuilder()
- .setName(name)
- .addAllEntities(entities)
- .addAllFeatures(
- features.entrySet().stream()
- .map(
- entry ->
- FeatureSpecV2.newBuilder()
- .setName(entry.getKey())
- .setValueType(entry.getValue())
- .putAllLabels(labels)
- .build())
- .collect(Collectors.toList()))
- .setMaxAge(Duration.newBuilder().setSeconds(3600).build())
- .setBatchSource(
- DataSource.newBuilder()
- .setEventTimestampColumn("ts")
- .setType(DataSource.SourceType.BATCH_FILE)
- .setFileOptions(
- FileOptions.newBuilder()
- .setFileFormat(
- FileFormat.newBuilder()
- .setParquetFormat(ParquetFormat.newBuilder().build())
- .build())
- .setFileUrl("/dev/null")
- .build())
- .build())
- .putAllLabels(labels)
- .build();
- }
-
- public static FeatureTableSpec createFeatureTableSpec(
- String name,
- List entities,
- ImmutableMap features,
- int maxAgeSecs,
- Map labels) {
-
- return FeatureTableSpec.newBuilder()
- .setName(name)
- .addAllEntities(entities)
- .addAllFeatures(
- features.entrySet().stream()
- .map(
- entry ->
- FeatureSpecV2.newBuilder()
- .setName(entry.getKey())
- .setValueType(entry.getValue())
- .putAllLabels(labels)
- .build())
- .collect(Collectors.toList()))
- .setMaxAge(Duration.newBuilder().setSeconds(maxAgeSecs).build())
- .putAllLabels(labels)
- .build();
- }
-
- public static DataSource createFileDataSourceSpec(
- String fileURL, String timestampColumn, String datePartitionColumn) {
- return DataSource.newBuilder()
- .setType(DataSource.SourceType.BATCH_FILE)
- .setFileOptions(
- FileOptions.newBuilder()
- .setFileFormat(createParquetFormat())
- .setFileUrl(fileURL)
- .build())
- .setEventTimestampColumn(timestampColumn)
- .setDatePartitionColumn(datePartitionColumn)
- .build();
- }
-
- public static DataSource createBigQueryDataSourceSpec(
- String bigQueryTableRef, String timestampColumn, String datePartitionColumn) {
- return DataSource.newBuilder()
- .setType(DataSource.SourceType.BATCH_BIGQUERY)
- .setBigqueryOptions(
- DataSource.BigQueryOptions.newBuilder().setTableRef(bigQueryTableRef).build())
- .setEventTimestampColumn(timestampColumn)
- .setDatePartitionColumn(datePartitionColumn)
- .build();
- }
-
- public static DataSource createKafkaDataSourceSpec(
- String servers, String topic, String classPath, String timestampColumn) {
- return DataSource.newBuilder()
- .setType(DataSource.SourceType.STREAM_KAFKA)
- .setKafkaOptions(
- KafkaOptions.newBuilder()
- .setTopic(topic)
- .setBootstrapServers(servers)
- .setMessageFormat(createProtoFormat("class.path"))
- .build())
- .setEventTimestampColumn(timestampColumn)
- .build();
- }
-
- public static ValueProto.Value createEmptyValue() {
- return ValueProto.Value.newBuilder().build();
- }
-
- public static ValueProto.Value createStrValue(String val) {
- return ValueProto.Value.newBuilder().setStringVal(val).build();
- }
-
- public static ValueProto.Value createDoubleValue(double value) {
- return ValueProto.Value.newBuilder().setDoubleVal(value).build();
- }
-
- public static ValueProto.Value createInt64Value(long value) {
- return ValueProto.Value.newBuilder().setInt64Val(value).build();
- }
-
- public static ServingAPIProto.FeatureReferenceV2 createFeatureReference(
- String featureTableName, String featureName) {
- return ServingAPIProto.FeatureReferenceV2.newBuilder()
- .setFeatureTable(featureTableName)
- .setName(featureName)
- .build();
- }
-
- public static ServingAPIProto.GetOnlineFeaturesRequestV2.EntityRow createEntityRow(
- String entityName, ValueProto.Value entityValue, long seconds) {
- return ServingAPIProto.GetOnlineFeaturesRequestV2.EntityRow.newBuilder()
- .setTimestamp(Timestamp.newBuilder().setSeconds(seconds))
- .putFields(entityName, entityValue)
- .build();
- }
-
- public static DataSource createKinesisDataSourceSpec(
- String region, String streamName, String classPath, String timestampColumn) {
- return DataSource.newBuilder()
- .setType(DataSource.SourceType.STREAM_KINESIS)
- .setKinesisOptions(
- KinesisOptions.newBuilder()
- .setRegion("ap-nowhere1")
- .setStreamName("stream")
- .setRecordFormat(createProtoFormat(classPath))
- .build())
- .setEventTimestampColumn(timestampColumn)
- .build();
- }
-
- public static FileFormat createParquetFormat() {
- return FileFormat.newBuilder().setParquetFormat(ParquetFormat.getDefaultInstance()).build();
- }
-
- public static StreamFormat createAvroFormat(String schemaJSON) {
- return StreamFormat.newBuilder()
- .setAvroFormat(AvroFormat.newBuilder().setSchemaJson(schemaJSON).build())
- .build();
- }
-
- public static StreamFormat createProtoFormat(String classPath) {
- return StreamFormat.newBuilder()
- .setProtoFormat(ProtoFormat.newBuilder().setClassPath(classPath).build())
- .build();
- }
-}
diff --git a/common-test/src/main/java/feast/common/it/ExternalApp.java b/common-test/src/main/java/feast/common/it/ExternalApp.java
deleted file mode 100644
index 3fa98b0d502..00000000000
--- a/common-test/src/main/java/feast/common/it/ExternalApp.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.it;
-
-import com.google.auto.value.AutoValue;
-import java.util.HashMap;
-import java.util.Map;
-import org.springframework.boot.Banner;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.core.env.MapPropertySource;
-import org.springframework.core.env.StandardEnvironment;
-import org.springframework.util.SocketUtils;
-import org.testcontainers.containers.PostgreSQLContainer;
-
-@AutoValue
-public abstract class ExternalApp {
- private ConfigurableApplicationContext appContext;
-
- abstract PostgreSQLContainer> getPostgreSQL();
-
- abstract String getName();
-
- abstract int getGRPCPort();
-
- abstract int getWebPort();
-
- abstract Map getProperties();
-
- abstract Class> getSpringApplication();
-
- public static Builder builder() {
- return new AutoValue_ExternalApp.Builder()
- .setProperties(new HashMap<>())
- .setWebPort(SocketUtils.findAvailableTcpPort());
- }
-
- @AutoValue.Builder
- public interface Builder {
- Builder setSpringApplication(Class> app);
-
- Builder setName(String name);
-
- Builder setPostgreSQL(PostgreSQLContainer> psql);
-
- Builder setGRPCPort(int port);
-
- Builder setWebPort(int port);
-
- Builder setProperties(Map properties);
-
- ExternalApp build();
- }
-
- public void start() {
- HashMap properties = new HashMap<>(getProperties());
- properties.put("spring.datasource.url", getPostgreSQL().getJdbcUrl());
- properties.put("spring.datasource.username", getPostgreSQL().getUsername());
- properties.put("spring.datasource.password", getPostgreSQL().getPassword());
- properties.put("grpc.server.port", getGRPCPort());
- properties.put("server.port", getWebPort());
-
- StandardEnvironment env = new StandardEnvironment();
- env.setDefaultProfiles(getName());
- env.getPropertySources().addFirst(new MapPropertySource("primary", properties));
-
- appContext =
- new SpringApplicationBuilder(getSpringApplication())
- .environment(env)
- .bannerMode(Banner.Mode.OFF)
- .run();
- }
-
- public void stop() {
- SpringApplication.exit(appContext);
- }
-}
diff --git a/common-test/src/main/java/feast/common/it/SimpleCoreClient.java b/common-test/src/main/java/feast/common/it/SimpleCoreClient.java
deleted file mode 100644
index 11fa6715dc8..00000000000
--- a/common-test/src/main/java/feast/common/it/SimpleCoreClient.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.it;
-
-import feast.proto.core.*;
-import feast.proto.core.CoreServiceProto.ApplyFeatureTableRequest;
-import feast.proto.core.FeatureTableProto.FeatureTableSpec;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public class SimpleCoreClient {
- private CoreServiceGrpc.CoreServiceBlockingStub stub;
-
- public SimpleCoreClient(CoreServiceGrpc.CoreServiceBlockingStub stub) {
- this.stub = stub;
- }
-
- public CoreServiceProto.ApplyEntityResponse simpleApplyEntity(
- String projectName, EntityProto.EntitySpecV2 spec) {
- return stub.applyEntity(
- CoreServiceProto.ApplyEntityRequest.newBuilder()
- .setProject(projectName)
- .setSpec(spec)
- .build());
- }
-
- public List simpleListEntities(String projectName) {
- return stub.listEntities(
- CoreServiceProto.ListEntitiesRequest.newBuilder()
- .setFilter(
- CoreServiceProto.ListEntitiesRequest.Filter.newBuilder()
- .setProject(projectName)
- .build())
- .build())
- .getEntitiesList();
- }
-
- public List simpleListEntities(
- String projectName, Map labels) {
- return stub.listEntities(
- CoreServiceProto.ListEntitiesRequest.newBuilder()
- .setFilter(
- CoreServiceProto.ListEntitiesRequest.Filter.newBuilder()
- .setProject(projectName)
- .putAllLabels(labels)
- .build())
- .build())
- .getEntitiesList();
- }
-
- public List simpleListEntities(
- CoreServiceProto.ListEntitiesRequest.Filter filter) {
- return stub.listEntities(
- CoreServiceProto.ListEntitiesRequest.newBuilder().setFilter(filter).build())
- .getEntitiesList();
- }
-
- public List simpleListFeatureTables(
- CoreServiceProto.ListFeatureTablesRequest.Filter filter) {
- return stub.listFeatureTables(
- CoreServiceProto.ListFeatureTablesRequest.newBuilder().setFilter(filter).build())
- .getTablesList();
- }
-
- public EntityProto.Entity simpleGetEntity(String projectName, String name) {
- return stub.getEntity(
- CoreServiceProto.GetEntityRequest.newBuilder()
- .setName(name)
- .setProject(projectName)
- .build())
- .getEntity();
- }
-
- public FeatureTableProto.FeatureTable simpleGetFeatureTable(String projectName, String name) {
- return stub.getFeatureTable(
- CoreServiceProto.GetFeatureTableRequest.newBuilder()
- .setName(name)
- .setProject(projectName)
- .build())
- .getTable();
- }
-
- public Map simpleListFeatures(
- String projectName, Map labels, List entities) {
- return stub.listFeatures(
- CoreServiceProto.ListFeaturesRequest.newBuilder()
- .setFilter(
- CoreServiceProto.ListFeaturesRequest.Filter.newBuilder()
- .setProject(projectName)
- .addAllEntities(entities)
- .putAllLabels(labels)
- .build())
- .build())
- .getFeaturesMap();
- }
-
- public Map simpleListFeatures(
- String projectName, String... entities) {
- return simpleListFeatures(projectName, Collections.emptyMap(), Arrays.asList(entities));
- }
-
- public CoreServiceProto.UpdateStoreResponse updateStore(StoreProto.Store store) {
- return stub.updateStore(
- CoreServiceProto.UpdateStoreRequest.newBuilder().setStore(store).build());
- }
-
- public void createProject(String name) {
- stub.createProject(CoreServiceProto.CreateProjectRequest.newBuilder().setName(name).build());
- }
-
- public void archiveProject(String name) {
- stub.archiveProject(CoreServiceProto.ArchiveProjectRequest.newBuilder().setName(name).build());
- }
-
- public String getFeastCoreVersion() {
- return stub.getFeastCoreVersion(
- CoreServiceProto.GetFeastCoreVersionRequest.getDefaultInstance())
- .getVersion();
- }
-
- public FeatureTableProto.FeatureTable applyFeatureTable(
- String projectName, FeatureTableSpec spec) {
- return stub.applyFeatureTable(
- ApplyFeatureTableRequest.newBuilder()
- .setProject(projectName)
- .setTableSpec(spec)
- .build())
- .getTable();
- }
-
- public void deleteFeatureTable(String projectName, String featureTableName) {
- stub.deleteFeatureTable(
- CoreServiceProto.DeleteFeatureTableRequest.newBuilder()
- .setProject(projectName)
- .setName(featureTableName)
- .build());
- }
-}
diff --git a/common-test/src/main/java/feast/common/it/SimpleIT.java b/common-test/src/main/java/feast/common/it/SimpleIT.java
deleted file mode 100644
index e8c5dff38c9..00000000000
--- a/common-test/src/main/java/feast/common/it/SimpleIT.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.it;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest()
-public class SimpleIT extends BaseIT {
- @Test
- public void test() {
- assert true;
- }
-}
diff --git a/common-test/src/main/java/feast/common/util/TestUtil.java b/common-test/src/main/java/feast/common/util/TestUtil.java
deleted file mode 100644
index ee355d3766f..00000000000
--- a/common-test/src/main/java/feast/common/util/TestUtil.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.util;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import feast.common.logging.AuditLogger;
-import feast.common.logging.config.LoggingProperties;
-import feast.proto.core.FeatureProto.FeatureSpecV2;
-import feast.proto.core.FeatureTableProto.FeatureTableSpec;
-import java.util.Comparator;
-import java.util.stream.Collectors;
-import org.springframework.boot.info.BuildProperties;
-
-public class TestUtil {
- /** Setup the audit logger. This call is required to use the audit logger when testing. */
- public static void setupAuditLogger() {
- LoggingProperties.AuditLogProperties properties = new LoggingProperties.AuditLogProperties();
- properties.setEnabled(true);
- LoggingProperties loggingProperties = new LoggingProperties();
- loggingProperties.setAudit(properties);
-
- BuildProperties buildProperties = mock(BuildProperties.class);
- when(buildProperties.getArtifact()).thenReturn("feast-core");
- when(buildProperties.getVersion()).thenReturn("0.6");
-
- new AuditLogger(loggingProperties, buildProperties);
- }
-
- /**
- * Compare if two Feature Table specs are equal. Disregards order of features/entities in spec.
- */
- public static boolean compareFeatureTableSpec(FeatureTableSpec spec, FeatureTableSpec otherSpec) {
- spec =
- spec.toBuilder()
- .clearFeatures()
- .addAllFeatures(
- spec.getFeaturesList().stream()
- .sorted(Comparator.comparing(FeatureSpecV2::getName))
- .collect(Collectors.toSet()))
- .clearEntities()
- .addAllEntities(spec.getEntitiesList().stream().sorted().collect(Collectors.toSet()))
- .build();
-
- otherSpec =
- otherSpec
- .toBuilder()
- .clearFeatures()
- .addAllFeatures(
- otherSpec.getFeaturesList().stream()
- .sorted(Comparator.comparing(FeatureSpecV2::getName))
- .collect(Collectors.toSet()))
- .clearEntities()
- .addAllEntities(
- otherSpec.getEntitiesList().stream().sorted().collect(Collectors.toSet()))
- .build();
-
- return spec.equals(otherSpec);
- }
-}
diff --git a/common/.openapi-generator-ignore b/common/.openapi-generator-ignore
deleted file mode 100644
index 6b177032ba1..00000000000
--- a/common/.openapi-generator-ignore
+++ /dev/null
@@ -1,20 +0,0 @@
-settings.gradle
-README.md
-pom.xml
-gradle
-git_push.sh
-build.sbt
-build.gradle
-.travis*
-.gitignore
-src/main/resources/api.yaml
-gradle*
-gradle/*
-gradle-wrapper.*
-gradle**
-gradle/
-src/main/java/feast/auth/providers/http/HttpAuthorizationProvider.java
-src/main/java/feast/auth/providers/http/ketoadaptor/api/CheckAccessApiController.java
-src/main/java/feast/auth/providers/http/ketoadaptor/api/KetoAuth.java
-src/main/AndroidManifest.xml
-.openapi-generator/
\ No newline at end of file
diff --git a/common/pom.xml b/common/pom.xml
deleted file mode 100644
index ce89e9c6a50..00000000000
--- a/common/pom.xml
+++ /dev/null
@@ -1,277 +0,0 @@
-
-
-
- 4.0.0
-
-
- feast-parent
- dev.feast
- ${revision}
-
-
- Feast Common
- Feast common module with functionality that can be reused
- feast-common
-
-
-
- dev.feast
- datatypes-java
- ${project.version}
- compile
-
-
- com.google.protobuf
- protobuf-java-util
-
-
-
- org.apache.commons
- commons-lang3
- 3.6
-
-
-
-
- org.projectlombok
- lombok
-
-
- com.google.auto.value
- auto-value-annotations
-
-
-
-
- com.google.code.gson
- gson
-
-
- io.gsonfire
- gson-fire
-
-
- com.fasterxml.jackson.core
- jackson-databind
-
-
- com.fasterxml.jackson.datatype
- jackson-datatype-jsr310
-
-
-
-
- org.springframework
- spring-context-support
-
-
- net.devh
- grpc-server-spring-boot-starter
-
-
- org.springframework.boot
- spring-boot-starter-logging
-
-
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.hibernate.validator
- hibernate-validator
-
-
-
-
- org.springframework.security
- spring-security-core
-
-
- org.springframework.security
- spring-security-config
-
-
- org.springframework.security
- spring-security-oauth2-resource-server
-
-
- org.springframework.security
- spring-security-oauth2-jose
-
-
- com.google.auth
- google-auth-library-oauth2-http
-
-
-
-
- org.openapitools
- jackson-databind-nullable
- 0.1.0
-
-
- io.swagger
- swagger-annotations
-
-
- com.squareup.okhttp3
- okhttp
-
-
- com.squareup.okhttp3
- logging-interceptor
-
-
- io.springfox
- springfox-swagger2
-
-
- io.springfox
- springfox-swagger-ui
-
-
-
-
- org.slf4j
- slf4j-api
-
-
- org.fluentd
- fluent-logger
- 0.3.1
-
-
-
-
- javax.xml.bind
- jaxb-api
-
-
- javax.validation
- validation-api
-
-
-
-
- com.google.code.findbugs
- jsr305
- 3.0.2
-
-
-
-
- org.hamcrest
- hamcrest-library
- test
-
-
- org.apache.kafka
- kafka-clients
- 2.5.0
-
-
- junit
- junit
- 4.12
-
-
- org.springframework
- spring-test
- test
-
-
- org.mockito
- mockito-core
- ${mockito.version}
- test
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.junit.vintage
- junit-vintage-engine
-
-
-
-
-
-
-
- org.openapitools
- openapi-generator-maven-plugin
- 4.3.1
-
-
- client
-
- generate
-
-
- ${project.basedir}/src/main/resources/api.yaml
- java
- ${feast.auth.providers.http.client.package.name}
- ${feast.auth.providers.http.client.package.name}.model
- ${feast.auth.providers.http.client.package.name}.api
- ${feast.auth.providers.http.client.package.name}.invoker
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- true
- java8
- Apache 2.0
- https://www.apache.org/licenses/LICENSE-2.0
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
-
- ${feast.auth.providers.http.client.package.name}.*
-
-
-
- org.jacoco
- jacoco-maven-plugin
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 3.0.0-M4
-
- -Xms2048m -Xmx2048m -Djdk.net.URLClassPath.disableClassPathURLCheck=true
-
-
-
-
-
diff --git a/common/src/main/java/feast/common/auth/authentication/DefaultJwtAuthenticationProvider.java b/common/src/main/java/feast/common/auth/authentication/DefaultJwtAuthenticationProvider.java
deleted file mode 100644
index 2b5c89f66e6..00000000000
--- a/common/src/main/java/feast/common/auth/authentication/DefaultJwtAuthenticationProvider.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.authentication;
-
-import java.util.Map;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
-import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
-import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider;
-
-/** Json Web Token Authentication Provider used to validate incoming requests to Feast Core. */
-public class DefaultJwtAuthenticationProvider implements AuthenticationProvider {
-
- private JwtAuthenticationProvider authProvider;
-
- /**
- * @param options String K/V pair of options to initialize the AuthenticationProvider with. Only
- * one option is currently configurable, the jwkEndpointURI.
- */
- public DefaultJwtAuthenticationProvider(Map options) {
- // Endpoint used to retrieve certificates to validate JWT token
- String jwkEndpointURI = options.get("jwkEndpointURI");
-
- // Provide a custom endpoint to retrieve certificates
- authProvider =
- new JwtAuthenticationProvider(NimbusJwtDecoder.withJwkSetUri(jwkEndpointURI).build());
- authProvider.setJwtAuthenticationConverter(new JwtAuthenticationConverter());
- }
-
- /**
- * Authenticate a request based on its Spring Security Authentication object
- *
- * @param authentication Authentication object which contains a JWT to validate
- * @return Returns the same authentication object after authentication
- */
- @Override
- public Authentication authenticate(Authentication authentication) throws AuthenticationException {
- return authProvider.authenticate(authentication);
- }
-
- @Override
- public boolean supports(Class> aClass) {
- return authProvider.supports(aClass);
- }
-}
diff --git a/common/src/main/java/feast/common/auth/authorization/AuthorizationProvider.java b/common/src/main/java/feast/common/auth/authorization/AuthorizationProvider.java
deleted file mode 100644
index e4e398883ec..00000000000
--- a/common/src/main/java/feast/common/auth/authorization/AuthorizationProvider.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.authorization;
-
-import org.springframework.security.core.Authentication;
-
-/**
- * AuthorizationProvider is the base interface that each AuthorizationProvider needs to implement in
- * order to authorize requests to Feast Core
- */
-public interface AuthorizationProvider {
-
- /**
- * Validates whether a user is allowed access to a project
- *
- * @param projectId Id of the Feast project
- * @param authentication Spring Security Authentication object
- * @return AuthorizationResult result of authorization query
- */
- AuthorizationResult checkAccessToProject(String projectId, Authentication authentication);
-}
diff --git a/common/src/main/java/feast/common/auth/authorization/AuthorizationResult.java b/common/src/main/java/feast/common/auth/authorization/AuthorizationResult.java
deleted file mode 100644
index 897cef6d37b..00000000000
--- a/common/src/main/java/feast/common/auth/authorization/AuthorizationResult.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.authorization;
-
-import java.util.Optional;
-import javax.annotation.Nullable;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * Implementation of AuthorizationProvider will return AuthorizationResult after validating incoming
- * requests to Feast Core. AuthorizationResult provides methods to check if user is authorized to
- * perform an action or not.
- */
-@Getter
-@AllArgsConstructor
-public class AuthorizationResult {
-
- /**
- * Method to create AuthorizationResult Object.
- *
- * @param allowed True If user is authorized, False otherwise.
- * @param failureReason Reason for authorization failure, if any
- * @return AuthorizationResult Object.
- */
- public static AuthorizationResult create(
- @Nullable boolean allowed, @Nullable String failureReason) {
- return new AuthorizationResult(allowed, Optional.ofNullable(failureReason));
- }
-
- /**
- * Method to create failed AuthorizationResult Object.
- *
- * @param failureReason Reason for authorization failure, if any or Null
- * @return AuthorizationResult Object.
- */
- public static AuthorizationResult failed(@Nullable String failureReason) {
- return new AuthorizationResult(false, Optional.ofNullable(failureReason));
- }
-
- /**
- * Method to create Success AuthorizationResult Object.
- *
- * @return AuthorizationResult Object.
- */
- public static AuthorizationResult success() {
- return new AuthorizationResult(true, Optional.empty());
- }
-
- private boolean allowed;
- private Optional failureReason;
-}
diff --git a/common/src/main/java/feast/common/auth/config/CacheConfiguration.java b/common/src/main/java/feast/common/auth/config/CacheConfiguration.java
deleted file mode 100644
index 7731906b88d..00000000000
--- a/common/src/main/java/feast/common/auth/config/CacheConfiguration.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.config;
-
-import com.google.common.cache.CacheBuilder;
-import feast.common.auth.utils.AuthUtils;
-import java.lang.reflect.Method;
-import java.util.concurrent.TimeUnit;
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cache.Cache;
-import org.springframework.cache.CacheManager;
-import org.springframework.cache.annotation.CachingConfigurer;
-import org.springframework.cache.annotation.EnableCaching;
-import org.springframework.cache.concurrent.ConcurrentMapCache;
-import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
-import org.springframework.cache.interceptor.CacheErrorHandler;
-import org.springframework.cache.interceptor.CacheResolver;
-import org.springframework.cache.interceptor.KeyGenerator;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.core.Authentication;
-
-/** CacheConfiguration class defines Cache settings for HttpAuthorizationProvider class. */
-@Configuration
-@EnableCaching
-@Setter
-@Getter
-public class CacheConfiguration implements CachingConfigurer {
-
- private static final int CACHE_SIZE = 10000;
-
- public static int TTL = 60;
-
- public static final String AUTHORIZATION_CACHE = "authorization";
-
- @Autowired SecurityProperties securityProperties;
-
- @Bean
- public CacheManager cacheManager() {
- ConcurrentMapCacheManager cacheManager =
- new ConcurrentMapCacheManager(AUTHORIZATION_CACHE) {
-
- @Override
- protected Cache createConcurrentMapCache(final String name) {
- return new ConcurrentMapCache(
- name,
- CacheBuilder.newBuilder()
- .expireAfterWrite(TTL, TimeUnit.SECONDS)
- .maximumSize(CACHE_SIZE)
- .build()
- .asMap(),
- false);
- }
- };
-
- return cacheManager;
- }
-
- /*
- * KeyGenerator used by {@link Cacheable} for caching authorization requests.
- * Key format : checkAccessToProject--
- */
- @Bean
- public KeyGenerator authKeyGenerator() {
- return (Object target, Method method, Object... params) -> {
- String projectId = (String) params[0];
- Authentication authentication = (Authentication) params[1];
- String subject =
- AuthUtils.getSubjectFromAuth(
- authentication,
- securityProperties.getAuthorization().getOptions().get("subjectClaim"));
- return String.format("%s-%s-%s", method.getName(), projectId, subject);
- };
- }
-
- @Override
- public CacheResolver cacheResolver() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public KeyGenerator keyGenerator() {
- return null;
- }
-
- @Override
- public CacheErrorHandler errorHandler() {
- // TODO Auto-generated method stub
- return null;
- }
-}
diff --git a/common/src/main/java/feast/common/auth/config/SecurityConfig.java b/common/src/main/java/feast/common/auth/config/SecurityConfig.java
deleted file mode 100644
index aa7f8a2b353..00000000000
--- a/common/src/main/java/feast/common/auth/config/SecurityConfig.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.config;
-
-import feast.common.auth.authentication.DefaultJwtAuthenticationProvider;
-import feast.common.auth.authorization.AuthorizationProvider;
-import feast.common.auth.providers.http.HttpAuthorizationProvider;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import net.devh.boot.grpc.server.security.authentication.BearerAuthenticationReader;
-import net.devh.boot.grpc.server.security.authentication.GrpcAuthenticationReader;
-import net.devh.boot.grpc.server.security.check.AccessPredicateVoter;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.access.AccessDecisionManager;
-import org.springframework.security.access.AccessDecisionVoter;
-import org.springframework.security.access.vote.UnanimousBased;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.authentication.ProviderManager;
-import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
-
-@Configuration
-public class SecurityConfig {
-
- private final SecurityProperties securityProperties;
-
- public SecurityConfig(SecurityProperties securityProperties) {
- this.securityProperties = securityProperties;
- }
-
- /**
- * Initializes an AuthenticationManager if authentication has been enabled.
- *
- * @return AuthenticationManager
- */
- @Bean
- @ConditionalOnProperty(prefix = "feast.security.authentication", name = "enabled")
- AuthenticationManager authenticationManager() {
- final List providers = new ArrayList<>();
-
- if (securityProperties.getAuthentication().isEnabled()) {
- switch (securityProperties.getAuthentication().getProvider()) {
- case "jwt":
- providers.add(
- new DefaultJwtAuthenticationProvider(
- securityProperties.getAuthentication().getOptions()));
- break;
- default:
- throw new IllegalArgumentException(
- "Please configure an Authentication Provider if you have enabled authentication.");
- }
- }
- return new ProviderManager(providers);
- }
-
- /**
- * Creates an AuthenticationReader that the AuthenticationManager will use to authenticate
- * requests
- *
- * @return GrpcAuthenticationReader
- */
- @Bean
- @ConditionalOnProperty(prefix = "feast.security.authentication", name = "enabled")
- GrpcAuthenticationReader authenticationReader() {
- return new BearerAuthenticationReader(BearerTokenAuthenticationToken::new);
- }
-
- /**
- * Creates an AccessDecisionManager if authorization is enabled. This object determines the policy
- * used to make authorization decisions.
- *
- * @return AccessDecisionManager
- */
- @Bean
- @ConditionalOnProperty(prefix = "feast.security.authorization", name = "enabled")
- AccessDecisionManager accessDecisionManager() {
- final List> voters = new ArrayList<>();
- voters.add(new AccessPredicateVoter());
- return new UnanimousBased(voters);
- }
-
- /**
- * Creates an AuthorizationProvider based on Feast configuration. This provider is available
- * through the security service.
- *
- * @return AuthorizationProvider used to validate access to Feast resources.
- */
- @Bean
- @ConditionalOnProperty(prefix = "feast.security.authorization", name = "enabled")
- AuthorizationProvider authorizationProvider() {
- if (securityProperties.getAuthentication().isEnabled()
- && securityProperties.getAuthorization().isEnabled()) {
- switch (securityProperties.getAuthorization().getProvider()) {
- case "http":
- // Merge authenticatoin and authorization options to create HttpAuthorizationProvider.
- Map options = securityProperties.getAuthorization().getOptions();
- options.putAll(securityProperties.getAuthentication().getOptions());
- return new HttpAuthorizationProvider(options);
- default:
- throw new IllegalArgumentException(
- "Please configure an Authorization Provider if you have enabled authorization.");
- }
- }
- return null;
- }
-}
diff --git a/common/src/main/java/feast/common/auth/config/SecurityProperties.java b/common/src/main/java/feast/common/auth/config/SecurityProperties.java
deleted file mode 100644
index 135cc4b5ed3..00000000000
--- a/common/src/main/java/feast/common/auth/config/SecurityProperties.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.config;
-
-import feast.common.validators.OneOfStrings;
-import java.util.Map;
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-public class SecurityProperties {
- private AuthenticationProperties authentication;
- private AuthorizationProperties authorization;
-
- // Bypass Authentication and Authorization at all HTTP endpoints at /api/v1
- private boolean disableRestControllerAuth;
-
- @Getter
- @Setter
- public static class AuthenticationProperties {
- // Enable authentication
- private boolean enabled;
-
- // Named authentication provider to use
- @OneOfStrings({"jwt"})
- private String provider;
-
- // K/V options to initialize the provider with
- private Map options;
- // Key for Subject Claim option which sets the name of the subject claim field in tokens.
- public static final String SUBJECT_CLAIM = "subjectClaim";
- }
-
- @Getter
- @Setter
- public static class AuthorizationProperties {
- // Enable authorization. Authentication must be enabled if authorization is enabled.
- private boolean enabled;
-
- // Named authorization provider to use.
- @OneOfStrings({"none", "http"})
- private String provider;
-
- // K/V options to initialize the provider with
- private Map options;
- }
-}
diff --git a/common/src/main/java/feast/common/auth/credentials/CoreAuthenticationProperties.java b/common/src/main/java/feast/common/auth/credentials/CoreAuthenticationProperties.java
deleted file mode 100644
index aa317cf8b15..00000000000
--- a/common/src/main/java/feast/common/auth/credentials/CoreAuthenticationProperties.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.credentials;
-
-import feast.common.validators.OneOfStrings;
-import java.util.Map;
-
-public class CoreAuthenticationProperties {
- // needs to be set to true if authentication is enabled on core
- private boolean enabled;
-
- // authentication provider to use
- @OneOfStrings({"google", "oauth"})
- private String provider;
-
- // K/V options to initialize the provider.
- Map options;
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
- public String getProvider() {
- return provider;
- }
-
- public void setProvider(String provider) {
- this.provider = provider;
- }
-
- public Map getOptions() {
- return options;
- }
-
- public void setOptions(Map options) {
- this.options = options;
- }
-}
diff --git a/common/src/main/java/feast/common/auth/credentials/GoogleAuthCredentials.java b/common/src/main/java/feast/common/auth/credentials/GoogleAuthCredentials.java
deleted file mode 100644
index 0f42325c5ac..00000000000
--- a/common/src/main/java/feast/common/auth/credentials/GoogleAuthCredentials.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.credentials;
-
-import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
-
-import com.google.auth.oauth2.IdTokenCredentials;
-import com.google.auth.oauth2.ServiceAccountCredentials;
-import io.grpc.CallCredentials;
-import io.grpc.Metadata;
-import io.grpc.Status;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * GoogleAuthCredentials provides a Google OIDC ID token for making authenticated gRPC calls. Uses
- * Google Application
- * Default credentials to obtain the OIDC token used for authentication. The given token will be
- * passed as authorization bearer token when making calls.
- */
-public class GoogleAuthCredentials extends CallCredentials {
- private final IdTokenCredentials credentials;
- private static final String BEARER_TYPE = "Bearer";
- private static final Metadata.Key AUTHORIZATION_METADATA_KEY =
- Metadata.Key.of("Authorization", ASCII_STRING_MARSHALLER);
-
- /**
- * Construct a new GoogleAuthCredentials with given options.
- *
- * @param options a map of options, Required unless specified: audience - Optional, Sets the
- * target audience of the token obtained.
- */
- public GoogleAuthCredentials(Map options) throws IOException {
- String targetAudience = options.getOrDefault("audience", "https://localhost");
- ServiceAccountCredentials serviceCreds =
- (ServiceAccountCredentials)
- ServiceAccountCredentials.getApplicationDefault()
- .createScoped(Arrays.asList("openid", "email"));
-
- credentials =
- IdTokenCredentials.newBuilder()
- .setIdTokenProvider(serviceCreds)
- .setTargetAudience(targetAudience)
- .build();
- }
-
- @Override
- public void applyRequestMetadata(
- RequestInfo requestInfo, Executor appExecutor, MetadataApplier applier) {
- appExecutor.execute(
- () -> {
- try {
- credentials.refreshIfExpired();
- Metadata headers = new Metadata();
- headers.put(
- AUTHORIZATION_METADATA_KEY,
- String.format("%s %s", BEARER_TYPE, credentials.getIdToken().getTokenValue()));
- applier.apply(headers);
- } catch (Throwable e) {
- applier.fail(Status.UNAUTHENTICATED.withCause(e));
- }
- });
- }
-
- @Override
- public void thisUsesUnstableApi() {
- // TODO Auto-generated method stub
-
- }
-}
diff --git a/common/src/main/java/feast/common/auth/credentials/JwtCallCredentials.java b/common/src/main/java/feast/common/auth/credentials/JwtCallCredentials.java
deleted file mode 100644
index f09f4ec9404..00000000000
--- a/common/src/main/java/feast/common/auth/credentials/JwtCallCredentials.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.credentials;
-
-import io.grpc.CallCredentials;
-import io.grpc.Metadata;
-import java.util.concurrent.Executor;
-
-/**
- * JWTCallCredentials provides/attaches a static JWT token for making authenticated gRPC calls. The
- * given token will be passed as authorization bearer token when making calls.
- */
-public final class JwtCallCredentials extends CallCredentials {
-
- private String jwt;
-
- public JwtCallCredentials(String jwt) {
- this.jwt = jwt;
- }
-
- @Override
- public void applyRequestMetadata(
- RequestInfo requestInfo, Executor executor, MetadataApplier metadataApplier) {
- Metadata metadata = new Metadata();
- metadata.put(
- Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER),
- String.format("Bearer %s", jwt));
- metadataApplier.apply(metadata);
- }
-
- @Override
- public void thisUsesUnstableApi() {
- // does nothing
- }
-}
diff --git a/common/src/main/java/feast/common/auth/credentials/OAuthCredentials.java b/common/src/main/java/feast/common/auth/credentials/OAuthCredentials.java
deleted file mode 100644
index 429fd7fdadd..00000000000
--- a/common/src/main/java/feast/common/auth/credentials/OAuthCredentials.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.credentials;
-
-import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
-
-import com.nimbusds.jose.util.JSONObjectUtils;
-import io.grpc.CallCredentials;
-import io.grpc.Metadata;
-import io.grpc.Status;
-import java.time.Instant;
-import java.util.Map;
-import java.util.concurrent.Executor;
-import javax.security.sasl.AuthenticationException;
-import net.minidev.json.JSONObject;
-import okhttp3.FormBody;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.RequestBody;
-import okhttp3.Response;
-import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
-
-/**
- * OAuthCredentials uses a OAuth OIDC ID token making authenticated gRPC calls. Makes an OAuth
- * request to obtain the OIDC token used for authentication. The given token will be passed as
- * authorization bearer token when making calls.
- */
-public class OAuthCredentials extends CallCredentials {
-
- private static final String JWK_ENDPOINT_URI = "jwkEndpointURI";
- static final String APPLICATION_JSON = "application/json";
- static final String CONTENT_TYPE = "content-type";
- static final String BEARER_TYPE = "Bearer";
- static final String GRANT_TYPE = "grant_type";
- static final String CLIENT_ID = "client_id";
- static final String CLIENT_SECRET = "client_secret";
- static final String AUDIENCE = "audience";
- static final String OAUTH_URL = "oauth_url";
- static final Metadata.Key AUTHORIZATION_METADATA_KEY =
- Metadata.Key.of("Authorization", ASCII_STRING_MARSHALLER);
-
- private OkHttpClient httpClient;
- private Request request;
- private String accessToken;
- private Instant tokenExpiryTime;
- private NimbusJwtDecoder jwtDecoder;
-
- /**
- * Constructs a new OAuthCredentials with given options.
- *
- * @param options a map of options, Required unless specified: grant_type - OAuth grant type.
- * Should be set as client_credentials audience - Sets the target audience of the token
- * obtained. client_id - Client id to use in the OAuth request. client_secret - Client securet
- * to use in the OAuth request. jwtEndpointURI - HTTPS URL used to retrieve a JWK that can be
- * used to decode the credential.
- */
- public OAuthCredentials(Map options) {
- this.httpClient = new OkHttpClient();
- if (!(options.containsKey(GRANT_TYPE)
- && options.containsKey(CLIENT_ID)
- && options.containsKey(AUDIENCE)
- && options.containsKey(CLIENT_SECRET)
- && options.containsKey(OAUTH_URL)
- && options.containsKey(JWK_ENDPOINT_URI))) {
- throw new AssertionError(
- "please configure the properties:"
- + " grant_type, client_id, client_secret, audience, oauth_url, jwkEndpointURI");
- }
- RequestBody requestBody =
- new FormBody.Builder()
- .add(GRANT_TYPE, options.get(GRANT_TYPE))
- .add(CLIENT_ID, options.get(CLIENT_ID))
- .add(CLIENT_SECRET, options.get(CLIENT_SECRET))
- .add(AUDIENCE, options.get(AUDIENCE))
- .build();
- this.request =
- new Request.Builder()
- .url(options.get(OAUTH_URL))
- .addHeader(CONTENT_TYPE, APPLICATION_JSON)
- .post(requestBody)
- .build();
- this.jwtDecoder = NimbusJwtDecoder.withJwkSetUri(options.get(JWK_ENDPOINT_URI)).build();
- }
-
- @Override
- public void thisUsesUnstableApi() {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void applyRequestMetadata(
- RequestInfo requestInfo, Executor appExecutor, MetadataApplier applier) {
- appExecutor.execute(
- () -> {
- try {
- // Fetches new token if it is not available or if token has expired.
- if (this.accessToken == null || Instant.now().isAfter(this.tokenExpiryTime)) {
- Response response = httpClient.newCall(request).execute();
- if (!response.isSuccessful()) {
- throw new AuthenticationException(response.message());
- }
- JSONObject json = JSONObjectUtils.parse(response.body().string());
- this.accessToken = json.getAsString("access_token");
- this.tokenExpiryTime = jwtDecoder.decode(this.accessToken).getExpiresAt();
- }
- Metadata headers = new Metadata();
- headers.put(
- AUTHORIZATION_METADATA_KEY, String.format("%s %s", BEARER_TYPE, this.accessToken));
- applier.apply(headers);
- } catch (Throwable e) {
- applier.fail(Status.UNAUTHENTICATED.withCause(e));
- }
- });
- }
-}
diff --git a/common/src/main/java/feast/common/auth/providers/http/HttpAuthorizationProvider.java b/common/src/main/java/feast/common/auth/providers/http/HttpAuthorizationProvider.java
deleted file mode 100644
index 041a6b8e1b0..00000000000
--- a/common/src/main/java/feast/common/auth/providers/http/HttpAuthorizationProvider.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.providers.http;
-
-import feast.common.auth.authorization.AuthorizationProvider;
-import feast.common.auth.authorization.AuthorizationResult;
-import feast.common.auth.config.CacheConfiguration;
-import feast.common.auth.config.SecurityProperties.AuthenticationProperties;
-import feast.common.auth.providers.http.client.api.DefaultApi;
-import feast.common.auth.providers.http.client.invoker.ApiClient;
-import feast.common.auth.providers.http.client.invoker.ApiException;
-import feast.common.auth.providers.http.client.model.CheckAccessRequest;
-import feast.common.auth.utils.AuthUtils;
-import java.util.Map;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.jwt.Jwt;
-
-/**
- * HTTPAuthorizationProvider uses an external HTTP service for authorizing requests. Please see
- * auth/src/main/resources/api.yaml for the API specification of this external service.
- */
-public class HttpAuthorizationProvider implements AuthorizationProvider {
-
- private static final Logger log = LoggerFactory.getLogger(HttpAuthorizationProvider.class);
-
- private final DefaultApi defaultApiClient;
-
- /**
- * The default subject claim is the key within the Authentication object where the user's identity
- * can be found
- */
- private final String subjectClaim;
-
- /**
- * Initializes the HTTPAuthorizationProvider
- *
- * @param options String K/V pair of options to initialize the provider with. Expects at least a
- * "basePath" for the provider URL
- */
- public HttpAuthorizationProvider(Map options) {
- if (options == null) {
- throw new IllegalArgumentException(
- "Cannot pass empty or null options to HTTPAuthorizationProvider");
- }
-
- ApiClient apiClient = new ApiClient();
- apiClient.setBasePath(options.get("authorizationUrl"));
- this.defaultApiClient = new DefaultApi(apiClient);
- subjectClaim = options.get(AuthenticationProperties.SUBJECT_CLAIM);
- }
-
- /**
- * Validates whether a user has access to a project. @Cacheable is using {@link
- * CacheConfiguration} settings to cache output of the method {@link AuthorizationResult} for a
- * specified duration set in cache settings.
- *
- * @param projectId Name of the Feast project
- * @param authentication Spring Security Authentication object
- * @return AuthorizationResult result of authorization query
- */
- @Cacheable(value = CacheConfiguration.AUTHORIZATION_CACHE, keyGenerator = "authKeyGenerator")
- public AuthorizationResult checkAccessToProject(String projectId, Authentication authentication) {
-
- CheckAccessRequest checkAccessRequest = new CheckAccessRequest();
- Object context = getContext(authentication);
- String subject = AuthUtils.getSubjectFromAuth(authentication, subjectClaim);
- String resource = "projects:" + projectId;
- checkAccessRequest.setAction("ALL");
- checkAccessRequest.setContext(context);
- checkAccessRequest.setResource(resource);
- checkAccessRequest.setSubject(subject);
- try {
- Jwt credentials = ((Jwt) authentication.getCredentials());
- // Make authorization request to external service
- feast.common.auth.providers.http.client.model.AuthorizationResult authResult =
- this.defaultApiClient.checkAccessPost(
- checkAccessRequest, "Bearer " + credentials.getTokenValue());
- if (authResult == null) {
- throw new RuntimeException(
- String.format(
- "Empty response returned for access to project %s for subject %s",
- projectId, subject));
- }
- if (authResult.getAllowed()) {
- // Successfully authenticated
- return AuthorizationResult.success();
- }
- } catch (ApiException e) {
- log.error("API exception has occurred during authorization: {}", e.getMessage(), e);
- }
-
- // Could not determine project membership, deny access.
- return AuthorizationResult.failed(
- String.format("Access denied to project %s for subject %s", projectId, subject));
- }
-
- /**
- * Extract a context object to send as metadata to the authorization service
- *
- * @param authentication Spring Security Authentication object
- * @return Returns a context object that will be serialized and sent as metadata to the
- * authorization service
- */
- private Object getContext(Authentication authentication) {
- // Not implemented yet, left empty
- return new Object();
- }
-}
diff --git a/common/src/main/java/feast/common/auth/service/AuthorizationService.java b/common/src/main/java/feast/common/auth/service/AuthorizationService.java
deleted file mode 100644
index 7d325e880d9..00000000000
--- a/common/src/main/java/feast/common/auth/service/AuthorizationService.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.service;
-
-import feast.common.auth.authorization.AuthorizationProvider;
-import feast.common.auth.authorization.AuthorizationResult;
-import feast.common.auth.config.SecurityProperties;
-import lombok.AllArgsConstructor;
-import org.springframework.beans.factory.ObjectProvider;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.stereotype.Service;
-
-@AllArgsConstructor
-@Service
-public class AuthorizationService {
-
- private final SecurityProperties securityProperties;
- private final AuthorizationProvider authorizationProvider;
-
- @Autowired
- public AuthorizationService(
- SecurityProperties securityProperties,
- ObjectProvider authorizationProvider) {
- this.securityProperties = securityProperties;
- this.authorizationProvider = authorizationProvider.getIfAvailable();
- }
-
- /**
- * Determine whether a user has access to a project.
- *
- * @param securityContext Spring Security Context used to identify a user or service.
- * @param project Name of the project for which membership should be tested.
- */
- public void authorizeRequest(SecurityContext securityContext, String project) {
- Authentication authentication = securityContext.getAuthentication();
- if (!this.securityProperties.getAuthorization().isEnabled()) {
- return;
- }
-
- AuthorizationResult result =
- this.authorizationProvider.checkAccessToProject(project, authentication);
- if (!result.isAllowed()) {
- throw new AccessDeniedException(result.getFailureReason().orElse("Access Denied"));
- }
- }
-}
diff --git a/common/src/main/java/feast/common/auth/utils/AuthUtils.java b/common/src/main/java/feast/common/auth/utils/AuthUtils.java
deleted file mode 100644
index e05fc70a184..00000000000
--- a/common/src/main/java/feast/common/auth/utils/AuthUtils.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.utils;
-
-import java.util.Map;
-import org.hibernate.validator.internal.constraintvalidators.bv.EmailValidator;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.jwt.Jwt;
-
-public class AuthUtils {
- // Suppresses default constructor, ensuring non-instantiability.
- private AuthUtils() {}
-
- /**
- * Get user email from their authentication object.
- *
- * @param authentication Spring Security Authentication object, used to extract user details
- * @param subjectClaim Indicates the claim where the subject can be found
- * @return String user email
- */
- public static String getSubjectFromAuth(Authentication authentication, String subjectClaim) {
- Jwt principle = ((Jwt) authentication.getPrincipal());
- Map claims = principle.getClaims();
- String subjectValue = (String) claims.getOrDefault(subjectClaim, "");
-
- if (subjectValue.isEmpty()) {
- throw new IllegalStateException(
- String.format("JWT does not have a valid claim %s.", subjectClaim));
- }
-
- if (subjectClaim.equals("email")) {
- boolean validEmail = (new EmailValidator()).isValid(subjectValue, null);
- if (!validEmail) {
- throw new IllegalStateException("JWT contains an invalid email address");
- }
- }
- return subjectValue;
- }
-}
diff --git a/common/src/main/java/feast/common/logging/AuditLogger.java b/common/src/main/java/feast/common/logging/AuditLogger.java
deleted file mode 100644
index 0b9901e1ade..00000000000
--- a/common/src/main/java/feast/common/logging/AuditLogger.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.logging;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.util.JsonFormat;
-import feast.common.logging.config.LoggingProperties;
-import feast.common.logging.config.LoggingProperties.AuditLogProperties;
-import feast.common.logging.entry.*;
-import feast.common.logging.entry.LogResource.ResourceType;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.Map;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.fluentd.logger.FluentLogger;
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
-import org.slf4j.event.Level;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.info.BuildProperties;
-import org.springframework.stereotype.Component;
-
-@Slf4j
-@Component
-public class AuditLogger {
- private static final String FLUENTD_DESTINATION = "fluentd";
- private static final Marker AUDIT_MARKER = MarkerFactory.getMarker("AUDIT_MARK");
- private static FluentLogger fluentLogger;
- private static AuditLogProperties properties;
- private static BuildProperties buildProperties;
-
- @Autowired
- public AuditLogger(LoggingProperties loggingProperties, BuildProperties buildProperties) {
- // Spring runs this constructor when creating the AuditLogger bean,
- // which allows us to populate the AuditLogger class with dependencies.
- // This allows us to use the dependencies in the AuditLogger's static methods
- AuditLogger.properties = loggingProperties.getAudit();
- AuditLogger.buildProperties = buildProperties;
- if (AuditLogger.properties.getMessageLogging() != null
- && AuditLogger.properties.getMessageLogging().isEnabled()) {
- AuditLogger.fluentLogger =
- FluentLogger.getLogger(
- "feast",
- AuditLogger.properties.getMessageLogging().getFluentdHost(),
- AuditLogger.properties.getMessageLogging().getFluentdPort());
- }
- }
-
- /**
- * Log the handling of a Protobuf message by a service call.
- *
- * @param entryBuilder with all fields set except instance.
- */
- public static void logMessage(Level level, MessageAuditLogEntry.Builder entryBuilder) {
- log(
- level,
- entryBuilder
- .setComponent(buildProperties.getArtifact())
- .setVersion(buildProperties.getVersion())
- .build());
- }
-
- /**
- * Log an action being taken on a specific resource
- *
- * @param level describing the severity of the log.
- * @param action name of the action being taken on specific resource.
- * @param resourceType the type of resource being logged.
- * @param resourceId resource specific identifier identifing the instance of the resource.
- */
- public static void logAction(
- Level level, String action, ResourceType resourceType, String resourceId) {
- log(
- level,
- ActionAuditLogEntry.of(
- buildProperties.getArtifact(),
- buildProperties.getArtifact(),
- LogResource.of(resourceType, resourceId),
- action));
- }
-
- /**
- * Log a transition in state/status in a specific resource.
- *
- * @param level describing the severity of the log.
- * @param status name of end status which the resource transition to.
- * @param resourceType the type of resource being logged.
- * @param resourceId resource specific identifier identifing the instance of the resource.
- */
- public static void logTransition(
- Level level, String status, ResourceType resourceType, String resourceId) {
- log(
- level,
- TransitionAuditLogEntry.of(
- buildProperties.getArtifact(),
- buildProperties.getArtifact(),
- LogResource.of(resourceType, resourceId),
- status));
- }
-
- /**
- * Log given {@link AuditLogEntry} at the given logging {@link Level} to the Audit log.
- *
- * @param level describing the severity of the log.
- * @param entry the {@link AuditLogEntry} to push to the audit log.
- */
- private static void log(Level level, AuditLogEntry entry) {
- // Check if audit logging is of this specific log entry enabled.
- if (!properties.isEnabled()) {
- return;
- }
-
- // Either forward log to logging layer or log to console
- String destination = properties.getMessageLogging().getDestination();
- if (destination.equals(FLUENTD_DESTINATION)) {
- if (entry.getKind() == AuditLogEntryKind.MESSAGE) {
- Map fluentdLogs = new HashMap<>();
- MessageAuditLogEntry messageAuditLogEntry = (MessageAuditLogEntry) entry;
- String releaseName;
-
- try {
- releaseName =
- StringUtils.defaultIfEmpty(
- System.getenv("RELEASE_NAME"), InetAddress.getLocalHost().getHostAddress());
- } catch (UnknownHostException e) {
- releaseName = StringUtils.defaultIfEmpty(System.getenv("RELEASE_NAME"), "");
- }
-
- fluentdLogs.put("id", messageAuditLogEntry.getId());
- fluentdLogs.put("identity", messageAuditLogEntry.getIdentity());
- fluentdLogs.put("service", messageAuditLogEntry.getService());
- fluentdLogs.put("status_code", messageAuditLogEntry.getStatusCode());
- fluentdLogs.put("method", messageAuditLogEntry.getMethod());
- fluentdLogs.put("release_name", releaseName);
- try {
- fluentdLogs.put("request", JsonFormat.printer().print(messageAuditLogEntry.getRequest()));
- fluentdLogs.put(
- "response", JsonFormat.printer().print(messageAuditLogEntry.getResponse()));
- } catch (InvalidProtocolBufferException e) {
- }
- fluentLogger.log("fluentd", fluentdLogs);
- }
- } else {
- // Log event to audit log through enabled formats
- String entryJSON = entry.toJSON();
- switch (level) {
- case TRACE:
- log.trace(AUDIT_MARKER, entryJSON);
- break;
- case DEBUG:
- log.debug(AUDIT_MARKER, entryJSON);
- break;
- case INFO:
- log.info(AUDIT_MARKER, entryJSON);
- break;
- case WARN:
- log.warn(AUDIT_MARKER, entryJSON);
- break;
- case ERROR:
- log.error(AUDIT_MARKER, entryJSON);
- break;
- }
- }
- }
-}
diff --git a/common/src/main/java/feast/common/logging/config/LoggingProperties.java b/common/src/main/java/feast/common/logging/config/LoggingProperties.java
deleted file mode 100644
index 06e62f71af3..00000000000
--- a/common/src/main/java/feast/common/logging/config/LoggingProperties.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.logging.config;
-
-import feast.common.validators.OneOfStrings;
-import javax.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-public class LoggingProperties {
- @NotNull private AuditLogProperties audit;
-
- @Getter
- @Setter
- public static class AuditLogProperties {
- // Whether to enable/disable audit logging entirely.
- private boolean enabled;
-
- private MessageLogging messageLogging;
-
- @Getter
- @Setter
- public static class MessageLogging {
- // Whether to enable/disable message level (ie request/response) audit logging.
- private boolean enabled;
-
- // Whether to log to console or fluentd
- @OneOfStrings({"console", "fluentd"})
- private String destination;
-
- // fluentD service host for external (request/response) logging.
- private String fluentdHost;
-
- // fluentD service port for external (request/response) logging.
- private Integer fluentdPort;
- }
- }
-}
diff --git a/common/src/main/java/feast/common/logging/entry/ActionAuditLogEntry.java b/common/src/main/java/feast/common/logging/entry/ActionAuditLogEntry.java
deleted file mode 100644
index cec85b736a6..00000000000
--- a/common/src/main/java/feast/common/logging/entry/ActionAuditLogEntry.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.logging.entry;
-
-import com.google.auto.value.AutoValue;
-
-/** ActionAuditLogEntry records an action being taken on a specific resource */
-@AutoValue
-public abstract class ActionAuditLogEntry extends AuditLogEntry {
- /** The name of the action taken on the resource. */
- public abstract String getAction();
-
- /** The target resource of which the action was taken on. */
- public abstract LogResource getResource();
-
- /**
- * Create an {@link AuditLogEntry} that records an action being taken on a specific resource.
- *
- * @param component The name of th Feast component producing this {@link AuditLogEntry}.
- * @param version The version of Feast producing this {@link AuditLogEntry}.
- * @param resource The target resource of which the action was taken on.
- * @param action The name of the action being taken on the given resource.
- */
- public static ActionAuditLogEntry of(
- String component, String version, LogResource resource, String action) {
- return new AutoValue_ActionAuditLogEntry(
- component, version, AuditLogEntryKind.ACTION, action, resource);
- }
-}
diff --git a/common/src/main/java/feast/common/logging/entry/AuditLogEntry.java b/common/src/main/java/feast/common/logging/entry/AuditLogEntry.java
deleted file mode 100644
index 9aa8fcb8c5c..00000000000
--- a/common/src/main/java/feast/common/logging/entry/AuditLogEntry.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.logging.entry;
-
-import com.google.gson.Gson;
-
-/**
- * AuditLogEntry represents a single audit Log Entry. Audit log entry can converted into string with
- * {{@link #toString()} for human readable representation. Or structured JSON with {{@link
- * #toJSON()} for a machine parsable representation.
- */
-public abstract class AuditLogEntry {
- /** Declare Log Type to allow external Logging systems to filter out {@link AuditLogEntry} */
- public final String logType = "FeastAuditLogEntry";
-
- public final String application = "Feast";
-
- /** The name of the Feast component producing this {@link AuditLogEntry} */
- public abstract String getComponent();
-
- /** The version of Feast producing this {@link AuditLogEntry} */
- public abstract String getVersion();
-
- public abstract AuditLogEntryKind getKind();
-
- /** Return a structured JSON representation of this {@link AuditLogEntry} */
- public String toJSON() {
- Gson gson = new Gson();
- return gson.toJson(this);
- }
-}
diff --git a/common/src/main/java/feast/common/logging/entry/AuditLogEntryKind.java b/common/src/main/java/feast/common/logging/entry/AuditLogEntryKind.java
deleted file mode 100644
index d673f6bdb30..00000000000
--- a/common/src/main/java/feast/common/logging/entry/AuditLogEntryKind.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.logging.entry;
-
-/** AuditLogEntryKind lists the various kinds of {@link AuditLogEntry} */
-public enum AuditLogEntryKind {
- MESSAGE,
- ACTION,
- TRANSITION,
-}
diff --git a/common/src/main/java/feast/common/logging/entry/LogResource.java b/common/src/main/java/feast/common/logging/entry/LogResource.java
deleted file mode 100644
index 1d0345a4042..00000000000
--- a/common/src/main/java/feast/common/logging/entry/LogResource.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.logging.entry;
-
-import com.google.auto.value.AutoValue;
-
-@AutoValue
-/**
- * LogResource is used in {@link AuditLogEntry} to reference a specific resource as the subject of
- * the log
- */
-public abstract class LogResource {
- public enum ResourceType {
- JOB,
- FEATURE_TABLE
- }
-
- public abstract ResourceType getType();
-
- public abstract String getId();
-
- public static LogResource of(ResourceType type, String id) {
- return new AutoValue_LogResource(type, id);
- }
-}
diff --git a/common/src/main/java/feast/common/logging/entry/MessageAuditLogEntry.java b/common/src/main/java/feast/common/logging/entry/MessageAuditLogEntry.java
deleted file mode 100644
index 745cc1283ae..00000000000
--- a/common/src/main/java/feast/common/logging/entry/MessageAuditLogEntry.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.logging.entry;
-
-import com.google.auto.value.AutoValue;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-import com.google.protobuf.Empty;
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.Message;
-import com.google.protobuf.util.JsonFormat;
-import io.grpc.Status.Code;
-import java.lang.reflect.Type;
-import java.util.UUID;
-
-/** MessageAuditLogEntry records the handling of a Protobuf message by a service call. */
-@AutoValue
-public abstract class MessageAuditLogEntry extends AuditLogEntry {
- /** Id used to identify the service call that the log entry is recording */
- public abstract UUID getId();
-
- /** The name of the service that was used to handle the service call. */
- public abstract String getService();
-
- /** The name of the method that was used to handle the service call. */
- public abstract String getMethod();
-
- /** The request Protobuf {@link Message} that was passed to the Service in the service call. */
- public abstract Message getRequest();
-
- /**
- * The response Protobuf {@link Message} that was passed to the Service in the service call. May
- * be an {@link Empty} protobuf no request could be collected due to an error.
- */
- public abstract Message getResponse();
-
- /**
- * The authenticated identity that was assumed during the handling of the service call. For
- * example, the user id or email that identifies the user making the call. Empty if the service
- * call is not authenticated.
- */
- public abstract String getIdentity();
-
- /** The result status code of the service call. */
- public abstract Code getStatusCode();
-
- @AutoValue.Builder
- public abstract static class Builder {
- public abstract Builder setId(UUID id);
-
- public abstract Builder setComponent(String component);
-
- public abstract Builder setVersion(String component);
-
- public abstract Builder setKind(AuditLogEntryKind kind);
-
- public abstract Builder setService(String name);
-
- public abstract Builder setMethod(String name);
-
- public abstract Builder setRequest(Message request);
-
- public abstract Builder setResponse(Message response);
-
- public abstract Builder setIdentity(String identity);
-
- public abstract Builder setStatusCode(Code statusCode);
-
- public abstract MessageAuditLogEntry build();
- }
-
- public static MessageAuditLogEntry.Builder newBuilder() {
- return new AutoValue_MessageAuditLogEntry.Builder()
- .setKind(AuditLogEntryKind.MESSAGE)
- .setId(UUID.randomUUID());
- }
-
- @Override
- public String toJSON() {
- // GSON requires custom typeadapter (serializer) to convert Protobuf messages to JSON properly
- Gson gson =
- new GsonBuilder()
- .registerTypeAdapter(
- Message.class,
- new JsonSerializer() {
- @Override
- public JsonElement serialize(
- Message message, Type type, JsonSerializationContext context) {
- try {
- String messageJSON = JsonFormat.printer().print(message);
- return new JsonParser().parse(messageJSON);
- } catch (InvalidProtocolBufferException e) {
-
- throw new RuntimeException(
- "Unexpected exception converting Protobuf to JSON", e);
- }
- }
- })
- .create();
- return gson.toJson(this);
- }
-}
diff --git a/common/src/main/java/feast/common/logging/entry/TransitionAuditLogEntry.java b/common/src/main/java/feast/common/logging/entry/TransitionAuditLogEntry.java
deleted file mode 100644
index 0f139b7bdbd..00000000000
--- a/common/src/main/java/feast/common/logging/entry/TransitionAuditLogEntry.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.logging.entry;
-
-import com.google.auto.value.AutoValue;
-
-/** TransitionAuditLogEntry records a transition in state/status in a specific resource. */
-@AutoValue
-public abstract class TransitionAuditLogEntry extends AuditLogEntry {
- /** The resource which the state/status transition occured. */
- public abstract LogResource getResource();
-
- /** The end status with the resource transition to. */
- public abstract String getStatus();
-
- /**
- * Construct a new {@link AuditLogEntry} to record a transition in state/status in a specific
- * resource.
- *
- * @param component The name of th Feast component producing this {@link AuditLogEntry}.
- * @param version The version of Feast producing this {@link AuditLogEntry}.
- * @param resource the resource which the transtion occured
- * @param status the end status which the resource transitioned to.
- */
- public static TransitionAuditLogEntry of(
- String component, String version, LogResource resource, String status) {
- return new AutoValue_TransitionAuditLogEntry(
- component, version, AuditLogEntryKind.TRANSITION, resource, status);
- }
-}
diff --git a/common/src/main/java/feast/common/logging/interceptors/GrpcMessageInterceptor.java b/common/src/main/java/feast/common/logging/interceptors/GrpcMessageInterceptor.java
deleted file mode 100644
index da895f0093b..00000000000
--- a/common/src/main/java/feast/common/logging/interceptors/GrpcMessageInterceptor.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.logging.interceptors;
-
-import com.google.protobuf.Empty;
-import com.google.protobuf.Message;
-import feast.common.auth.config.SecurityProperties;
-import feast.common.auth.config.SecurityProperties.AuthenticationProperties;
-import feast.common.auth.utils.AuthUtils;
-import feast.common.logging.AuditLogger;
-import feast.common.logging.config.LoggingProperties;
-import feast.common.logging.entry.MessageAuditLogEntry;
-import io.grpc.ForwardingServerCall.SimpleForwardingServerCall;
-import io.grpc.ForwardingServerCallListener.SimpleForwardingServerCallListener;
-import io.grpc.Metadata;
-import io.grpc.ServerCall;
-import io.grpc.ServerCall.Listener;
-import io.grpc.ServerCallHandler;
-import io.grpc.ServerInterceptor;
-import io.grpc.Status;
-import java.util.Map;
-import org.slf4j.event.Level;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.lang.Nullable;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Component;
-
-/**
- * GrpcMessageInterceptor intercepts a GRPC calls to log handling of GRPC messages to the Audit Log.
- * Intercepts the incoming and outgoing messages logs them to the audit log, together with method
- * name and assumed authenticated identity (if authentication is enabled). NOTE:
- * GrpcMessageInterceptor assumes that all service calls are unary (ie single request/response).
- */
-@Component
-public class GrpcMessageInterceptor implements ServerInterceptor {
- private SecurityProperties securityProperties;
- private LoggingProperties loggingProperties;
-
- /**
- * Construct GrpcMessageIntercetor.
- *
- * @param loggingProperties properties used to configure logging interceptor.
- * @param securityProperties If provided, will output the subject claim specified in
- * securityProperties as identity in {@link MessageAuditLogEntry} instead.
- */
- @Autowired
- public GrpcMessageInterceptor(
- LoggingProperties loggingProperties, @Nullable SecurityProperties securityProperties) {
- this.securityProperties = securityProperties;
- this.loggingProperties = loggingProperties;
- }
-
- @Override
- public Listener interceptCall(
- ServerCall call, Metadata headers, ServerCallHandler next) {
- // Disable the message logging interceptor entirely if message logging is disabled.
- if (!loggingProperties.getAudit().getMessageLogging().isEnabled()) {
- return next.startCall(call, headers);
- }
-
- MessageAuditLogEntry.Builder entryBuilder = MessageAuditLogEntry.newBuilder();
- // default response/request message to empty proto in log entry.
- // request could be empty when the client closes the connection before sending a request
- // message.
- // response could be unset when the service encounters an error when processsing the service
- // call.
- entryBuilder.setRequest(Empty.newBuilder().build());
- entryBuilder.setResponse(Empty.newBuilder().build());
-
- // Unpack service & method name from call
- // full method name is in format ./
- String fullMethodName = call.getMethodDescriptor().getFullMethodName();
- entryBuilder.setService(
- fullMethodName.substring(fullMethodName.lastIndexOf(".") + 1, fullMethodName.indexOf("/")));
- entryBuilder.setMethod(fullMethodName.substring(fullMethodName.indexOf("/") + 1));
-
- // Attempt Extract current authenticated identity.
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- String identity = (authentication != null) ? getIdentity(authentication) : "";
- entryBuilder.setIdentity(identity);
-
- // Register forwarding call to intercept outgoing response and log to audit log
- call =
- new SimpleForwardingServerCall(call) {
- @Override
- public void sendMessage(RespT message) {
- // 2. Track the response & Log entry to audit logger
- super.sendMessage(message);
- entryBuilder.setResponse((Message) message);
- }
-
- @Override
- public void close(Status status, Metadata trailers) {
- super.close(status, trailers);
- // 3. Log the message log entry to the audit log
- Level logLevel = (status.isOk()) ? Level.INFO : Level.ERROR;
- entryBuilder.setStatusCode(status.getCode());
- AuditLogger.logMessage(logLevel, entryBuilder);
- }
- };
-
- ServerCall.Listener listener = next.startCall(call, headers);
- return new SimpleForwardingServerCallListener(listener) {
- @Override
- // Register listener to intercept incoming request messages and log to audit log
- public void onMessage(ReqT message) {
- super.onMessage(message);
- // 1. Track the request.
- entryBuilder.setRequest((Message) message);
- }
- };
- }
-
- /**
- * Extract current authenticated identity from given {@link Authentication}. Extracts subject
- * claim if specified in AuthorizationProperties, otherwise returns authentication subject.
- */
- private String getIdentity(Authentication authentication) {
- // use subject claim as identity if set in security authorization properties
- if (securityProperties != null) {
- Map options = securityProperties.getAuthentication().getOptions();
- if (options.containsKey(AuthenticationProperties.SUBJECT_CLAIM)) {
- try {
- return AuthUtils.getSubjectFromAuth(
- authentication, options.get(AuthenticationProperties.SUBJECT_CLAIM));
- } catch (IllegalStateException e) {
- // could not extract claim, revert to authenticated name.
- return authentication.getName();
- }
- }
- }
- return authentication.getName();
- }
-}
diff --git a/common/src/main/java/feast/common/models/FeatureTable.java b/common/src/main/java/feast/common/models/FeatureTable.java
deleted file mode 100644
index d4712e7a013..00000000000
--- a/common/src/main/java/feast/common/models/FeatureTable.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.models;
-
-import feast.proto.core.FeatureTableProto.FeatureTableSpec;
-import feast.proto.serving.ServingAPIProto.FeatureReferenceV2;
-
-public class FeatureTable {
-
- /**
- * Accepts FeatureTableSpec object and returns its reference in String
- * "project/featuretable_name".
- *
- * @param featureTableSpec {@link FeatureTableSpec}
- * @return String format of FeatureTableReference
- */
- public static String getFeatureTableStringRef(String project, FeatureTableSpec featureTableSpec) {
- return String.format("%s/%s", project, featureTableSpec.getName());
- }
-
- /**
- * Accepts FeatureReferenceV2 object and returns its reference in String
- * "project/featuretable_name".
- *
- * @param featureReference {@link FeatureReferenceV2}
- * @return String format of FeatureTableReference
- */
- public static String getFeatureTableStringRef(
- String project, FeatureReferenceV2 featureReference) {
- return String.format("%s/%s", project, featureReference.getFeatureTable());
- }
-}
diff --git a/common/src/main/java/feast/common/models/FeatureV2.java b/common/src/main/java/feast/common/models/FeatureV2.java
deleted file mode 100644
index 8debca33b9f..00000000000
--- a/common/src/main/java/feast/common/models/FeatureV2.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.models;
-
-import feast.proto.serving.ServingAPIProto.FeatureReferenceV2;
-
-public class FeatureV2 {
-
- /**
- * Accepts FeatureReferenceV2 object and returns its reference in String
- * "featuretable_name:feature_name".
- *
- * @param featureReference {@link FeatureReferenceV2}
- * @return String format of FeatureReferenceV2
- */
- public static String getFeatureStringRef(FeatureReferenceV2 featureReference) {
- String ref = featureReference.getName();
- if (!featureReference.getFeatureTable().isEmpty()) {
- ref = featureReference.getFeatureTable() + ":" + ref;
- }
- return ref;
- }
-}
diff --git a/common/src/main/java/feast/common/models/Store.java b/common/src/main/java/feast/common/models/Store.java
deleted file mode 100644
index 1701b0bb3a2..00000000000
--- a/common/src/main/java/feast/common/models/Store.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.models;
-
-import feast.proto.core.StoreProto.Store.Subscription;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-public class Store {
-
- /**
- * Accepts a comma-delimited string and converts it to a list of Subscription class objects.
- *
- * @param subscriptions String formatted Subscriptions, comma delimited.
- * @return List of Subscription class objects
- */
- public static List parseSubFromStr(String subscriptions) {
- List allSubscriptions =
- Arrays.stream(subscriptions.split(","))
- .map(subscriptionStr -> convertStringToSubscription(subscriptionStr))
- .collect(Collectors.toList());
-
- return allSubscriptions;
- }
-
- /**
- * Accepts a comma-delimited string and converts it to a list of Subscription class objects, with
- * exclusions filtered out.
- *
- * @param subscriptions String formatted Subscriptions, comma delimited.
- * @return List of Subscription class objects
- */
- public static List parseSubFromStrWithoutExclusions(String subscriptions) {
- List allSubscriptions =
- Arrays.stream(subscriptions.split(","))
- .map(subscriptionStr -> convertStringToSubscription(subscriptionStr))
- .collect(Collectors.toList());
-
- allSubscriptions =
- allSubscriptions.stream().filter(sub -> !sub.getExclude()).collect(Collectors.toList());
-
- return allSubscriptions;
- }
-
- /**
- * Accepts a Subscription class object and returns it in string format
- *
- * @param subscription Subscription class to be converted to string format
- * @return String formatted Subscription class
- */
- public static String parseSubscriptionFrom(Subscription subscription) {
- if (subscription.getName().isEmpty() || subscription.getProject().isEmpty()) {
- throw new IllegalArgumentException(
- String.format("Missing arguments in subscription string: %s", subscription.toString()));
- }
-
- return String.format(
- "%s:%s:%s", subscription.getProject(), subscription.getName(), subscription.getExclude());
- }
-
- /**
- * Accepts a exclude parameter to determine whether to return subscriptions that are excluded.
- *
- * @param subscription String formatted Subscription to be converted to Subscription class
- * @return Subscription class with its respective attributes
- */
- public static Subscription convertStringToSubscription(String subscription) {
- if (subscription.equals("")) {
- return Subscription.newBuilder().build();
- }
- String[] split = subscription.split(":");
- if (split.length == 2) {
- // Backward compatibility check
- return Subscription.newBuilder().setProject(split[0]).setName(split[1]).build();
- }
- return Subscription.newBuilder()
- .setProject(split[0])
- .setName(split[1])
- .setExclude(Boolean.parseBoolean(split[2]))
- .build();
- }
-
- /**
- * The current use of this function is to determine whether a FeatureRow is subscribed to a
- * Featureset.
- *
- * @param subscriptions List of Subscriptions available in Store
- * @param projectName Project name used for matching Subscription's Project
- * @param featureSetName Featureset name used for matching Subscription's Featureset
- * @return boolean flag to signify if FeatureRow is subscribed to Featureset
- */
- public static boolean isSubscribedToFeatureSet(
- List subscriptions, String projectName, String featureSetName) {
- // Case 1: Highest priority check, to exclude all matching subscriptions with excluded flag =
- // true
- for (Subscription sub : subscriptions) {
- // If configuration missing, fail
- if (sub.getProject().isEmpty() || sub.getName().isEmpty()) {
- throw new IllegalArgumentException(
- String.format("Subscription is missing arguments: %s", sub.toString()));
- }
- // Match feature set name to pattern
- Pattern patternName = getNamePattern(sub);
- Pattern patternProject = getProjectPattern(sub);
- // SubCase: Project name and feature set name matches and excluded flag is true
- if (patternProject.matcher(projectName).matches()
- && patternName.matcher(featureSetName).matches()
- && sub.getExclude()) {
- return false;
- }
- }
- // Case 2: Featureset is not excluded, check if it is included in the current subscriptions
- // filteredSubscriptions only contain subscriptions with excluded flag = false
- List filteredSubscriptions =
- subscriptions.stream().filter(sub -> !sub.getExclude()).collect(Collectors.toList());
-
- for (Subscription filteredSub : filteredSubscriptions) {
- // Match feature set name to pattern
- Pattern patternName = getNamePattern(filteredSub);
- Pattern patternProject = getProjectPattern(filteredSub);
- // SubCase: Project name and feature set name matches
- if (patternProject.matcher(projectName).matches()
- && patternName.matcher(featureSetName).matches()) {
- return true;
- }
- }
- return false;
- }
-
- private static Pattern getProjectPattern(Subscription subscription) {
- String subProject = subscription.getProject();
- if (!subscription.getProject().contains(".*")) {
- subProject = subProject.replace("*", ".*");
- }
-
- return Pattern.compile(subProject);
- }
-
- private static Pattern getNamePattern(Subscription subscription) {
- String subName = subscription.getName();
- if (!subscription.getProject().contains(".*")) {
- subName = subName.replace("*", ".*");
- }
-
- return Pattern.compile(subName);
- }
-}
diff --git a/common/src/main/java/feast/common/util/KafkaSerialization.java b/common/src/main/java/feast/common/util/KafkaSerialization.java
deleted file mode 100644
index 62c31a63bb7..00000000000
--- a/common/src/main/java/feast/common/util/KafkaSerialization.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.util;
-
-import com.google.protobuf.GeneratedMessageV3;
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.Message;
-import com.google.protobuf.Parser;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import org.apache.kafka.common.serialization.Deserializer;
-import org.apache.kafka.common.serialization.Serializer;
-
-/*
-Serializer & Deserializer implementation to write & read protobuf object from/to kafka
- */
-public class KafkaSerialization {
- public static class ProtoSerializer implements Serializer {
- @Override
- public byte[] serialize(String topic, T data) {
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- try {
- data.writeTo(stream);
- } catch (IOException e) {
- throw new RuntimeException(
- String.format(
- "Unable to serialize object of type %s. Reason: %s",
- data.getClass().getName(), e.getCause().getMessage()));
- }
-
- return stream.toByteArray();
- }
- }
-
- public static class ProtoDeserializer implements Deserializer {
- private Parser parser;
-
- public ProtoDeserializer(Parser parser) {
- this.parser = parser;
- }
-
- @Override
- public T deserialize(String topic, byte[] data) {
- try {
- return parser.parseFrom(data);
- } catch (InvalidProtocolBufferException e) {
- throw new RuntimeException(
- String.format(
- "Unable to deserialize object from topic %s. Reason: %s",
- topic, e.getCause().getMessage()));
- }
- }
- }
-}
diff --git a/common/src/main/java/feast/common/validators/OneOfStringValidator.java b/common/src/main/java/feast/common/validators/OneOfStringValidator.java
deleted file mode 100644
index 42428bd8c05..00000000000
--- a/common/src/main/java/feast/common/validators/OneOfStringValidator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.validators;
-
-import java.util.Arrays;
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
-
-/** Validates whether a string value is found within a collection. */
-public class OneOfStringValidator implements ConstraintValidator {
-
- /** Values that are permitted for a specific instance of this validator */
- String[] allowedValues;
-
- /**
- * Initialize the OneOfStringValidator with a collection of allowed String values.
- *
- * @param constraintAnnotation
- */
- @Override
- public void initialize(OneOfStrings constraintAnnotation) {
- allowedValues = constraintAnnotation.value();
- }
-
- /**
- * Validates whether a string value is found within the collection defined in the annotation.
- *
- * @param value String value that should be validated
- * @param context Provides contextual data and operation when applying a given constraint
- * validator
- * @return Boolean value indicating whether the string is found within the allowed values.
- */
- @Override
- public boolean isValid(String value, ConstraintValidatorContext context) {
- return Arrays.asList(allowedValues).contains(value);
- }
-}
diff --git a/common/src/main/java/feast/common/validators/OneOfStrings.java b/common/src/main/java/feast/common/validators/OneOfStrings.java
deleted file mode 100644
index b0acfae09d9..00000000000
--- a/common/src/main/java/feast/common/validators/OneOfStrings.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.validators;
-
-import java.lang.annotation.*;
-import javax.validation.Constraint;
-import javax.validation.Payload;
-
-/**
- * Annotation for String "one of" validation. Allows for the definition of a collection through an
- * annotation. The collection is used to test values defined in the object.
- */
-@Target({
- ElementType.METHOD,
- ElementType.FIELD,
- ElementType.ANNOTATION_TYPE,
- ElementType.CONSTRUCTOR,
- ElementType.PARAMETER
-})
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Constraint(validatedBy = OneOfStringValidator.class)
-public @interface OneOfStrings {
- /** @return Default error message that is returned if the incorrect value is set */
- String message() default "Field value must be one of the following: {value}";
-
- /** Allows for the specification of validation groups to which this constraint belongs. */
- Class>[] groups() default {};
-
- /** An attribute payload that can be used to assign custom payload objects to a constraint. */
- Class extends Payload>[] payload() default {};
-
- /** @return Default value that is returned if no allowed values are configured */
- String[] value() default {};
-}
diff --git a/common/src/main/resources/api.yaml b/common/src/main/resources/api.yaml
deleted file mode 100644
index 73ddaf2c2dd..00000000000
--- a/common/src/main/resources/api.yaml
+++ /dev/null
@@ -1,117 +0,0 @@
-openapi: 3.0.1
-info:
- description: 'Feast Authorization Server'
- license:
- name: Apache 2.0
- url: http://www.apache.org/licenses/LICENSE-2.0.html
- title: Feast Authorization Server
- version: 1.0.0
-servers:
- - url: /
-paths:
- /healthz:
- get:
- responses:
- "200":
- description: Online
- "500":
- description: Offline
- /readiness:
- get:
- responses:
- "200":
- description: Ready
- "500":
- description: Not Ready
- /checkAccess:
- post:
- parameters:
- - name: Authorization
- in: header
- description: Auth token
- schema:
- type: string
- operationId: check_access_post
- requestBody:
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/checkAccessRequest'
- description: Request containing user, resource, and action information. Used to make an authorization decision.
- required: true
- responses:
- "200":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/authorizationResult'
- description: Authorization passed response
- "403":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/authorizationResult'
- description: Authorization failed response
- "500":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/inline_response_500'
- description: The standard error format
- summary: Check whether request is authorized to access a specific resource
- x-codegen-request-body-name: body
-components:
- schemas:
- checkAccessRequest:
- example:
- action: 'read'
- context: '{}'
- resource: 'feast:project'
- subject: 'me@example.com'
- properties:
- action:
- description: Action is the action that is being taken on the requested resource.
- type: string
- context:
- description: Context is the request's environmental context.
- properties: {}
- type: object
- resource:
- description: Resource is the resource that access is requested to.
- type: string
- subject:
- description: Subject is the subject that is requesting access, typically the user.
- type: string
- title: Input for checking if a request is allowed or not.
- type: object
- authorizationResult:
- example:
- allowed: true
- properties:
- allowed:
- description: Allowed is true if the request should be allowed and false
- otherwise.
- type: boolean
- required:
- - allowed
- title: AuthorizationResult is the result of an access control decision. It contains
- the decision outcome.
- type: object
- inline_response_500:
- properties:
- code:
- format: int64
- type: integer
- details:
- items:
- properties: {}
- type: object
- type: array
- message:
- type: string
- reason:
- type: string
- request:
- type: string
- status:
- type: string
\ No newline at end of file
diff --git a/common/src/main/resources/log4j2.xml b/common/src/main/resources/log4j2.xml
deleted file mode 100644
index c75c2db13cc..00000000000
--- a/common/src/main/resources/log4j2.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
- %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${hostName} --- [%15.15t] %-40.40c{1.} : %m%n%ex
-
-
- {"time":"%d{yyyy-MM-dd'T'HH:mm:ssXXX}","hostname":"${hostName}","severity":"%p","message":%m}%n%ex
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/common/src/test/java/feast/common/auth/authorization/HttpAuthorizationProviderCachingTest.java b/common/src/test/java/feast/common/auth/authorization/HttpAuthorizationProviderCachingTest.java
deleted file mode 100644
index f303801c301..00000000000
--- a/common/src/test/java/feast/common/auth/authorization/HttpAuthorizationProviderCachingTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.auth.authorization;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.collect.ImmutableMap;
-import feast.common.auth.config.CacheConfiguration;
-import feast.common.auth.config.SecurityProperties;
-import feast.common.auth.config.SecurityProperties.AuthenticationProperties;
-import feast.common.auth.config.SecurityProperties.AuthorizationProperties;
-import feast.common.auth.providers.http.HttpAuthorizationProvider;
-import feast.common.auth.providers.http.client.api.DefaultApi;
-import feast.common.auth.providers.http.client.model.AuthorizationResult;
-import feast.common.auth.providers.http.client.model.CheckAccessRequest;
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.mockito.internal.util.reflection.FieldSetter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.jwt.Jwt;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringRunner;
-
-@RunWith(SpringRunner.class)
-@ContextConfiguration(
- classes = {CacheConfiguration.class, HttpAuthorizationProviderCachingTest.Config.class})
-public class HttpAuthorizationProviderCachingTest {
-
- // static since field needs to updated in provider() bean
- private static DefaultApi api = Mockito.mock(DefaultApi.class);
-
- @Autowired AuthorizationProvider provider;
-
- @Configuration
- static class Config {
- @Bean
- SecurityProperties securityProps() {
- // setting TTL static variable in SecurityProperties bean, since CacheConfiguration bean is
- // dependent on SecurityProperties.
- CacheConfiguration.TTL = 1;
- AuthenticationProperties authentication = Mockito.mock(AuthenticationProperties.class);
- AuthorizationProperties authorization = new AuthorizationProperties();
- authorization.setEnabled(true);
- authorization.setProvider("http");
- authorization.setOptions(ImmutableMap.of("authorizationUrl", "localhost"));
-
- authentication.setOptions(ImmutableMap.of("subjectClaim", "email"));
-
- SecurityProperties sp = new SecurityProperties();
- sp.setAuthentication(authentication);
- sp.setAuthorization(authorization);
- return sp;
- }
-
- @Bean
- AuthorizationProvider provider() throws NoSuchFieldException, SecurityException {
- Map options = new HashMap<>();
- options.put("authorizationUrl", "localhost");
- options.put("subjectClaim", "email");
- HttpAuthorizationProvider provider = new HttpAuthorizationProvider(options);
- FieldSetter.setField(provider, provider.getClass().getDeclaredField("defaultApiClient"), api);
- return provider;
- }
- }
-
- @Test
- public void testCheckAccessToProjectShouldReadFromCacheWhenAvailable() throws Exception {
- Authentication auth = Mockito.mock(Authentication.class);
- Jwt jwt = Mockito.mock(Jwt.class);
- Map claims = new HashMap<>();
- claims.put("email", "test@test.com");
- doReturn(jwt).when(auth).getCredentials();
- doReturn(jwt).when(auth).getPrincipal();
- doReturn(claims).when(jwt).getClaims();
- doReturn("test_token").when(jwt).getTokenValue();
- AuthorizationResult authResult = new AuthorizationResult();
- authResult.setAllowed(true);
- doReturn(authResult)
- .when(api)
- .checkAccessPost(any(CheckAccessRequest.class), any(String.class));
-
- // Should save the result in cache
- provider.checkAccessToProject("test", auth);
- // Should read from cache
- provider.checkAccessToProject("test", auth);
- verify(api, times(1)).checkAccessPost(any(CheckAccessRequest.class), any(String.class));
-
- // cache ttl is set to 1 second for testing.
- Thread.sleep(1100);
-
- // Should make an invocation to external service
- provider.checkAccessToProject("test", auth);
- verify(api, times(2)).checkAccessPost(any(CheckAccessRequest.class), any(String.class));
- // Should read from cache
- provider.checkAccessToProject("test", auth);
- verify(api, times(2)).checkAccessPost(any(CheckAccessRequest.class), any(String.class));
- }
-}
diff --git a/common/src/test/java/feast/common/logging/entry/AuditLogEntryTest.java b/common/src/test/java/feast/common/logging/entry/AuditLogEntryTest.java
deleted file mode 100644
index cf355e09e4b..00000000000
--- a/common/src/test/java/feast/common/logging/entry/AuditLogEntryTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.logging.entry;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import feast.common.logging.entry.LogResource.ResourceType;
-import feast.proto.serving.ServingAPIProto.FeatureReferenceV2;
-import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesRequestV2;
-import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponse;
-import feast.proto.serving.ServingAPIProto.GetOnlineFeaturesResponse.FieldValues;
-import feast.proto.types.ValueProto.Value;
-import io.grpc.Status;
-import java.util.Arrays;
-import java.util.List;
-import org.junit.Test;
-
-public class AuditLogEntryTest {
- public List getTestAuditLogs() {
- GetOnlineFeaturesRequestV2 requestSpec =
- GetOnlineFeaturesRequestV2.newBuilder()
- .addAllFeatures(
- Arrays.asList(
- FeatureReferenceV2.newBuilder()
- .setFeatureTable("featuretable_1")
- .setName("feature1")
- .build(),
- FeatureReferenceV2.newBuilder()
- .setFeatureTable("featuretable_1")
- .setName("feature2")
- .build()))
- .build();
-
- GetOnlineFeaturesResponse responseSpec =
- GetOnlineFeaturesResponse.newBuilder()
- .addAllFieldValues(
- Arrays.asList(
- FieldValues.newBuilder()
- .putFields(
- "featuretable_1:feature_1", Value.newBuilder().setInt32Val(32).build())
- .build(),
- FieldValues.newBuilder()
- .putFields(
- "featuretable_1:feature2", Value.newBuilder().setInt32Val(64).build())
- .build()))
- .build();
-
- return Arrays.asList(
- MessageAuditLogEntry.newBuilder()
- .setComponent("feast-serving")
- .setVersion("0.9")
- .setService("ServingService")
- .setMethod("getOnlineFeatures")
- .setRequest(requestSpec)
- .setResponse(responseSpec)
- .setStatusCode(Status.OK.getCode())
- .setIdentity("adam@no.such.email")
- .build(),
- ActionAuditLogEntry.of(
- "core", "0.9", LogResource.of(ResourceType.JOB, "kafka-to-redis"), "CREATE"),
- TransitionAuditLogEntry.of(
- "core", "0.9", LogResource.of(ResourceType.FEATURE_TABLE, "featuretable_1"), "READY"));
- }
-
- @Test
- public void shouldReturnJSONRepresentationOfAuditLog() {
- for (AuditLogEntry auditLog : getTestAuditLogs()) {
- // Check that auditLog's toJSON() returns valid JSON
- String logJSON = auditLog.toJSON();
- System.out.println(logJSON);
- JsonParser parser = new JsonParser();
-
- // check basic fields are present in JSON representation.
- JsonObject logObject = parser.parse(logJSON).getAsJsonObject();
- assertThat(logObject.getAsJsonPrimitive("logType").getAsString(), equalTo(auditLog.logType));
- assertThat(
- logObject.getAsJsonPrimitive("kind").getAsString(), equalTo(auditLog.getKind().name()));
- }
- }
-}
diff --git a/common/src/test/java/feast/common/models/FeaturesTest.java b/common/src/test/java/feast/common/models/FeaturesTest.java
deleted file mode 100644
index 180f7e4e697..00000000000
--- a/common/src/test/java/feast/common/models/FeaturesTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.models;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsEqual.equalTo;
-
-import feast.proto.serving.ServingAPIProto.FeatureReferenceV2;
-import org.junit.Before;
-import org.junit.Test;
-
-public class FeaturesTest {
-
- private FeatureReferenceV2 featureReference;
-
- @Before
- public void setUp() {
- featureReference =
- FeatureReferenceV2.newBuilder()
- .setFeatureTable("featuretable_1")
- .setName("feature1")
- .build();
- }
-
- @Test
- public void shouldReturnFeatureStringRef() {
- String actualFeatureStringRef = FeatureV2.getFeatureStringRef(featureReference);
- String expectedFeatureStringRef = "featuretable_1:feature1";
-
- assertThat(actualFeatureStringRef, equalTo(expectedFeatureStringRef));
- }
-}
diff --git a/common/src/test/java/feast/common/models/StoreTest.java b/common/src/test/java/feast/common/models/StoreTest.java
deleted file mode 100644
index 1acba12d2b6..00000000000
--- a/common/src/test/java/feast/common/models/StoreTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.common.models;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertTrue;
-
-import feast.proto.core.StoreProto.Store.Subscription;
-import java.util.Arrays;
-import java.util.List;
-import org.junit.Before;
-import org.junit.Test;
-
-public class StoreTest {
-
- private List allSubscriptions;
-
- @Before
- public void setUp() {
-
- Subscription emptySubscription = Subscription.newBuilder().build();
- Subscription subscription1 = Subscription.newBuilder().setProject("*").setName("*").build();
- Subscription subscription2 =
- Subscription.newBuilder().setProject("project1").setName("fs_2").build();
- Subscription subscription3 =
- Subscription.newBuilder().setProject("project1").setName("fs_1").setExclude(true).build();
- allSubscriptions =
- Arrays.asList(emptySubscription, subscription1, subscription2, subscription3);
- }
-
- @Test
- public void shouldReturnSubscriptionsBasedOnStr() {
- String subscriptions = "project1:fs_1:true,project1:fs_2";
- List actual1 = Store.parseSubFromStr(subscriptions);
- List expected1 = Arrays.asList(allSubscriptions.get(2), allSubscriptions.get(3));
-
- List actual2 = Store.parseSubFromStrWithoutExclusions(subscriptions);
- List expected2 = Arrays.asList(allSubscriptions.get(2));
-
- assertTrue(actual1.containsAll(expected1) && expected1.containsAll(actual1));
- assertTrue(actual2.containsAll(expected2) && expected2.containsAll(actual2));
- }
-
- @Test
- public void shouldReturnStringBasedOnSubscription() {
- // Case: default exclude should be false
- String actual1 = Store.parseSubscriptionFrom(allSubscriptions.get(2));
- Subscription sub1 = allSubscriptions.get(2);
- String expected1 = sub1.getProject() + ":" + sub1.getName() + ":" + sub1.getExclude();
-
- // Case: explicit setting of exclude to true
- String actual2 = Store.parseSubscriptionFrom(allSubscriptions.get(3));
- Subscription sub2 = allSubscriptions.get(3);
- String expected2 = sub2.getProject() + ":" + sub2.getName() + ":" + sub2.getExclude();
-
- assertThat(actual1, equalTo(expected1));
- assertThat(actual2, equalTo(expected2));
- }
-
- @Test
- public void shouldSubscribeToFeatureSet() {
- allSubscriptions = allSubscriptions.subList(2, 4);
- // Case: excluded flag = true
- boolean actual1 = Store.isSubscribedToFeatureSet(allSubscriptions, "project1", "fs_1");
- boolean expected1 = false;
-
- // Case: excluded flag = false
- boolean actual2 = Store.isSubscribedToFeatureSet(allSubscriptions, "project1", "fs_2");
- boolean expected2 = true;
-
- // Case: featureset does not exist
- boolean actual3 =
- Store.isSubscribedToFeatureSet(allSubscriptions, "project1", "fs_nonexistent");
- boolean expected3 = false;
-
- assertThat(actual1, equalTo(expected1));
- assertThat(actual2, equalTo(expected2));
- assertThat(actual3, equalTo(expected3));
- }
-}
diff --git a/core/.gitignore b/core/.gitignore
deleted file mode 100644
index fc240cb6e9a..00000000000
--- a/core/.gitignore
+++ /dev/null
@@ -1,40 +0,0 @@
-### Scratch files ###
-scratch_redis*
-
-### Local Environment ###
-*local*.env
-
-### Gradle ###
-.gradle
-**/build/
-!gradle/wrapper/gradle-wrapper.jar
-feast-serving.jar
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-/out/
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-
-## Static site ##
-static
-
-## Feast Temporary Files ##
-/temp/
\ No newline at end of file
diff --git a/core/README.md b/core/README.md
deleted file mode 100644
index 8f5b6f03bf5..00000000000
--- a/core/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-### Getting Started Guide for Feast Core Developers
-
-Pre-requisites:
-- [Maven](https://maven.apache.org/install.html) build tool version 3.6.x
-- A running Postgres instance. For easier to get started, please configure the database like so
- ```
- database: postgres
- user: postgres
- password: password
- ```
-- A running Redis instance
- ```
- host: localhost
- port: 6379
- ```
-- Access to Google Cloud BigQuery (optional)
-- Access to Kafka brokers (to test starting ingestion jobs from Feast Core)
-
-Run the following maven command to start Feast Core GRPC service running on port 6565 locally
-```bash
-# Using configuration from src/main/resources/application.yml
-mvn spring-boot:run
-# Using configuration from custom location e.g. /tmp/config.application.yml
-mvn spring-boot:run -Dspring.config.location=/tmp/config.application.yml
-```
-
-If you have [grpc_cli](https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md) installed, you can check that Feast Core is running
-```
-grpc_cli ls localhost:6565
-grpc_cli call localhost:6565 GetFeastCoreVersion ""
-grpc_cli call localhost:6565 ListStores ""
-```
\ No newline at end of file
diff --git a/core/lombok.config b/core/lombok.config
deleted file mode 100644
index 8f7e8aa1ac9..00000000000
--- a/core/lombok.config
+++ /dev/null
@@ -1 +0,0 @@
-lombok.addLombokGeneratedAnnotation = true
\ No newline at end of file
diff --git a/core/pom.xml b/core/pom.xml
deleted file mode 100644
index 7a34b794db2..00000000000
--- a/core/pom.xml
+++ /dev/null
@@ -1,326 +0,0 @@
-
-
-
- 4.0.0
-
- dev.feast
- feast-parent
- ${revision}
-
-
- Feast Core
- Feature registry
- feast-core
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
- 11
-
-
-
-
- org.jacoco
- jacoco-maven-plugin
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
- false
-
-
-
- build-info
-
- build-info
-
-
-
-
-
-
- org.flywaydb
- flyway-maven-plugin
- ${flyway.version}
-
-
-
-
-
-
- dev.feast
- feast-common
- ${project.version}
-
-
- dev.feast
- feast-common-test
- ${project.version}
- test
-
-
-
-
- org.springframework.boot
- spring-boot-devtools
- true
-
-
-
- javax.inject
- javax.inject
- 1
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- org.springframework.boot
- spring-boot-starter-log4j2
-
-
- org.apache.logging.log4j
- log4j-web
-
-
- org.springframework.security
- spring-security-core
- ${spring.security.version}
-
-
- org.springframework.security
- spring-security-config
- ${spring.security.version}
-
-
- org.springframework.security.oauth
- spring-security-oauth2
- ${spring.security.oauth2.version}
-
-
- org.springframework.security
- spring-security-oauth2-client
- ${spring.security.version}
-
-
- org.springframework.security
- spring-security-web
- ${spring.security.version}
-
-
- org.springframework.security
- spring-security-oauth2-resource-server
- ${spring.security.version}
-
-
- org.springframework.security
- spring-security-oauth2-jose
- ${spring.security.version}
-
-
- net.devh
- grpc-server-spring-boot-starter
- ${grpc.spring.boot.starter.version}
-
-
- com.nimbusds
- nimbus-jose-jwt
- 8.2.1
-
-
- org.springframework.security
- spring-security-oauth2-core
- ${spring.security.version}
-
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
-
- org.springframework.boot
- spring-boot-starter-actuator
-
-
-
-
- org.springframework.boot
- spring-boot-configuration-processor
-
-
-
- io.grpc
- grpc-services
-
-
-
- io.grpc
- grpc-stub
-
-
-
- com.google.protobuf
- protobuf-java-util
-
-
-
- com.google.guava
- guava
-
-
-
- com.google.code.gson
- gson
- 2.8.5
-
-
- com.google.api-client
- google-api-client
- 1.30.9
-
-
- com.google.apis
- google-api-services-dataflow
- v1b3-rev20200305-1.30.9
-
-
- org.hibernate
- hibernate-core
-
-
-
-
- org.postgresql
- postgresql
- provided
- true
-
-
-
- org.springframework.kafka
- spring-kafka
-
-
-
-
- org.projectlombok
- lombok
- ${lombok.version}
-
-
-
- io.prometheus
- simpleclient
-
-
-
- io.prometheus
- simpleclient_servlet
-
-
- com.google.api.client
- google-api-client-googleapis-auth-oauth
- 1.2.3-alpha
-
-
- com.auth0
- jwks-rsa
- 0.11.0
-
-
-
- com.auth0
- java-jwt
- 3.10.0
-
-
-
- org.apache.commons
- commons-lang3
-
-
-
- joda-time
- joda-time
-
-
-
-
- com.jayway.jsonpath
- json-path-assert
- 2.2.0
- test
-
-
-
- javax.xml.bind
- jaxb-api
-
-
- org.flywaydb
- flyway-core
- ${flyway.version}
-
-
- org.hibernate.validator
- hibernate-validator-annotation-processor
- 6.1.2.Final
-
-
-
- sh.ory.keto
- keto-client
- 0.4.4-alpha.1
- test
-
-
- com.github.tomakehurst
- wiremock
- 2.27.0
- test
-
-
- org.apache.avro
- avro
- 1.8.2
- test
-
-
- com.squareup.okhttp
- okhttp
- 2.7.4
- test
-
-
- io.grpc
- grpc-testing
-
-
-
diff --git a/core/src/main/java/feast/core/CoreApplication.java b/core/src/main/java/feast/core/CoreApplication.java
deleted file mode 100644
index 957fdf50157..00000000000
--- a/core/src/main/java/feast/core/CoreApplication.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.core;
-
-import feast.core.config.FeastProperties;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
-import org.springframework.scheduling.annotation.EnableScheduling;
-
-@EnableScheduling
-@SpringBootApplication
-@EnableJpaRepositories(basePackages = "feast.core.dao")
-@EnableConfigurationProperties(FeastProperties.class)
-@Slf4j
-public class CoreApplication {
- public static void main(String[] args) {
- SpringApplication.run(CoreApplication.class, args);
- }
-}
diff --git a/core/src/main/java/feast/core/config/CoreSecurityConfig.java b/core/src/main/java/feast/core/config/CoreSecurityConfig.java
deleted file mode 100644
index 52911c3b223..00000000000
--- a/core/src/main/java/feast/core/config/CoreSecurityConfig.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.core.config;
-
-import feast.proto.core.CoreServiceGrpc;
-import io.grpc.health.v1.HealthGrpc;
-import lombok.extern.slf4j.Slf4j;
-import net.devh.boot.grpc.server.security.check.AccessPredicate;
-import net.devh.boot.grpc.server.security.check.GrpcSecurityMetadataSource;
-import net.devh.boot.grpc.server.security.check.ManualGrpcSecurityMetadataSource;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-@Slf4j
-@ComponentScan(
- basePackages = {
- "feast.common.auth.config",
- "feast.common.auth.service",
- "feast.common.logging.interceptors"
- })
-public class CoreSecurityConfig {
-
- /**
- * Creates a SecurityMetadataSource when authentication is enabled. This allows for the
- * configuration of endpoint level security rules.
- *
- * @return GrpcSecurityMetadataSource
- */
- @Bean
- @ConditionalOnProperty(prefix = "feast.security.authentication", name = "enabled")
- GrpcSecurityMetadataSource grpcSecurityMetadataSource() {
- final ManualGrpcSecurityMetadataSource source = new ManualGrpcSecurityMetadataSource();
-
- // Authentication is enabled for all gRPC endpoints
- source.setDefault(AccessPredicate.authenticated());
-
- // The following endpoints allow unauthenticated access
- source.set(CoreServiceGrpc.getGetFeastCoreVersionMethod(), AccessPredicate.permitAll());
- source.set(CoreServiceGrpc.getUpdateStoreMethod(), AccessPredicate.permitAll());
- source.set(HealthGrpc.getCheckMethod(), AccessPredicate.permitAll());
- return source;
- }
-}
diff --git a/core/src/main/java/feast/core/config/FeastProperties.java b/core/src/main/java/feast/core/config/FeastProperties.java
deleted file mode 100644
index fd926ea5da4..00000000000
--- a/core/src/main/java/feast/core/config/FeastProperties.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.core.config;
-
-import feast.common.auth.config.SecurityProperties;
-import feast.common.auth.config.SecurityProperties.AuthenticationProperties;
-import feast.common.auth.config.SecurityProperties.AuthorizationProperties;
-import feast.common.logging.config.LoggingProperties;
-import feast.common.validators.OneOfStrings;
-import feast.core.config.FeastProperties.StreamProperties.FeatureStreamOptions;
-import java.util.Set;
-import javax.annotation.PostConstruct;
-import javax.validation.ConstraintViolation;
-import javax.validation.ConstraintViolationException;
-import javax.validation.Validation;
-import javax.validation.Validator;
-import javax.validation.ValidatorFactory;
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-import javax.validation.constraints.Positive;
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.boot.info.BuildProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-
-@Getter
-@Setter
-@Configuration
-@ComponentScan("feast.common.logging")
-@ConfigurationProperties(prefix = "feast", ignoreInvalidFields = true)
-public class FeastProperties {
-
- /**
- * Instantiates a new Feast properties.
- *
- * @param buildProperties Feast build properties
- */
- @Autowired
- public FeastProperties(BuildProperties buildProperties) {
- setVersion(buildProperties.getVersion());
- }
-
- /** Instantiates a new Feast properties. */
- public FeastProperties() {}
-
- /* Feast Core Build Version */
- @NotBlank private String version = "unknown";
-
- @NotNull
- /* Feast Kafka stream properties */
- private StreamProperties stream;
-
- @NotNull private SecurityProperties security;
-
- @Bean
- SecurityProperties securityProperties() {
- return getSecurity();
- }
-
- /* Feast Audit Logging properties */
- @NotNull private LoggingProperties logging;
-
- @Bean
- LoggingProperties loggingProperties() {
- return getLogging();
- }
-
- /** Properties used to configure Feast's managed Kafka feature stream. */
- @Getter
- @Setter
- public static class StreamProperties {
-
- /* Feature stream type. Only "kafka" is supported. */
- @OneOfStrings({"kafka"})
- @NotBlank
- private String type;
-
- /* Feature stream options */
- @NotNull private FeatureStreamOptions options;
-
- /** Feature stream options */
- @Getter
- @Setter
- public static class FeatureStreamOptions {
-
- /* Kafka topic to use for feature sets without source topics. */
- @NotBlank private String topic = "feast-features";
-
- /**
- * Comma separated list of Kafka bootstrap servers. Used for feature sets without a defined
- * source.
- */
- @NotBlank private String bootstrapServers = "localhost:9092";
-
- /* Defines the number of copies of managed feature stream Kafka. */
- @Positive private short replicationFactor = 1;
-
- /* Number of Kafka partitions to to use for managed feature stream. */
- @Positive private int partitions = 1;
- }
- }
-
- /**
- * Validates all FeastProperties. This method runs after properties have been initialized and
- * individually and conditionally validates each class.
- */
- @PostConstruct
- public void validate() {
- ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
- Validator validator = factory.getValidator();
-
- // Validate root fields in FeastProperties
- Set> violations = validator.validate(this);
- if (!violations.isEmpty()) {
- throw new ConstraintViolationException(violations);
- }
-
- // Validate Stream properties
- Set> streamPropertyViolations =
- validator.validate(getStream());
- if (!streamPropertyViolations.isEmpty()) {
- throw new ConstraintViolationException(streamPropertyViolations);
- }
-
- // Validate Stream Options
- Set> featureStreamOptionsViolations =
- validator.validate(getStream().getOptions());
- if (!featureStreamOptionsViolations.isEmpty()) {
- throw new ConstraintViolationException(featureStreamOptionsViolations);
- }
-
- // Validate AuthenticationProperties
- Set> authenticationPropsViolations =
- validator.validate(getSecurity().getAuthentication());
- if (!authenticationPropsViolations.isEmpty()) {
- throw new ConstraintViolationException(authenticationPropsViolations);
- }
-
- // Validate AuthorizationProperties
- Set> authorizationPropsViolations =
- validator.validate(getSecurity().getAuthorization());
- if (!authorizationPropsViolations.isEmpty()) {
- throw new ConstraintViolationException(authorizationPropsViolations);
- }
- }
-}
diff --git a/core/src/main/java/feast/core/config/JPAConfig.java b/core/src/main/java/feast/core/config/JPAConfig.java
deleted file mode 100644
index dada6c9d3a6..00000000000
--- a/core/src/main/java/feast/core/config/JPAConfig.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.core.config;
-
-import javax.persistence.EntityManagerFactory;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.orm.jpa.JpaTransactionManager;
-import org.springframework.transaction.PlatformTransactionManager;
-
-/** Configuration of JPA related services and beans for the core application. */
-@Configuration
-@Slf4j
-public class JPAConfig {
- @Bean
- public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
- JpaTransactionManager transactionManager = new JpaTransactionManager();
- transactionManager.setEntityManagerFactory(emf);
-
- return transactionManager;
- }
-}
diff --git a/core/src/main/java/feast/core/config/MonitoringConfig.java b/core/src/main/java/feast/core/config/MonitoringConfig.java
deleted file mode 100644
index 5fc6b8280e5..00000000000
--- a/core/src/main/java/feast/core/config/MonitoringConfig.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.core.config;
-
-import feast.core.dao.FeatureTableRepository;
-import feast.core.dao.StoreRepository;
-import feast.core.metrics.collector.FeastResourceCollector;
-import feast.core.metrics.collector.JVMResourceCollector;
-import io.prometheus.client.exporter.MetricsServlet;
-import javax.servlet.http.HttpServlet;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.web.servlet.ServletRegistrationBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class MonitoringConfig {
-
- private static final String PROMETHEUS_METRICS_PATH = "/metrics";
-
- /**
- * Add Prometheus exposition to an existing HTTP server using servlets.
- *
- *
https://github.com/prometheus/client_java/tree/b61dd232a504e20dad404a2bf3e2c0b8661c212a#http
- *
- * @return HTTP servlet for returning metrics data
- */
- @Bean
- public ServletRegistrationBean metricsServlet() {
- return new ServletRegistrationBean<>(new MetricsServlet(), PROMETHEUS_METRICS_PATH);
- }
-
- /**
- * Register custom Prometheus collector that exports metrics about Feast Resources.
- *
- *
For example: total number of registered feature tables and stores.
- *
- * @param featureTableRepository {@link FeatureTableRepository}
- * @param storeRepository {@link StoreRepository}
- * @return {@link FeastResourceCollector}
- */
- @Bean
- @Autowired
- public FeastResourceCollector feastResourceCollector(
- FeatureTableRepository featureTableRepository, StoreRepository storeRepository) {
- FeastResourceCollector collector =
- new FeastResourceCollector(featureTableRepository, storeRepository);
- collector.register();
- return collector;
- }
-
- /**
- * Register custom Prometheus collector that exports metrics about JVM resource usage.
- *
- * @return {@link JVMResourceCollector}
- */
- @Bean
- public JVMResourceCollector jvmResourceCollector() {
- JVMResourceCollector jvmResourceCollector = new JVMResourceCollector();
- jvmResourceCollector.register();
- return jvmResourceCollector;
- }
-}
diff --git a/core/src/main/java/feast/core/config/WebMvcConfig.java b/core/src/main/java/feast/core/config/WebMvcConfig.java
deleted file mode 100644
index 5d6a6b8eceb..00000000000
--- a/core/src/main/java/feast/core/config/WebMvcConfig.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.core.config;
-
-import java.util.List;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.http.converter.HttpMessageConverter;
-import org.springframework.http.converter.protobuf.ProtobufJsonFormatHttpMessageConverter;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-/** Configuration for the spring web MVC layer */
-@Configuration
-public class WebMvcConfig implements WebMvcConfigurer {
- /**
- * Get a json-protobuf converter.
- *
- * @return ProtobufJsonFormatHttpMessageConverter
- */
- @Bean
- ProtobufJsonFormatHttpMessageConverter getProtobufHttpMessageConverter() {
- return new ProtobufJsonFormatHttpMessageConverter();
- }
-
- /** Register json-protobuf converter. */
- @Override
- public void configureMessageConverters(List> converters) {
- converters.add(getProtobufHttpMessageConverter());
- }
-}
diff --git a/core/src/main/java/feast/core/config/WebSecurityConfig.java b/core/src/main/java/feast/core/config/WebSecurityConfig.java
deleted file mode 100644
index 0f481115a2f..00000000000
--- a/core/src/main/java/feast/core/config/WebSecurityConfig.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.core.config;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-
-/**
- * WebSecurityConfig disables auto configuration of Spring HTTP Security and allows security methods
- * to be overridden
- */
-@Configuration
-@EnableWebSecurity
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
-
- private final FeastProperties feastProperties;
-
- @Autowired
- public WebSecurityConfig(FeastProperties feastProperties) {
- this.feastProperties = feastProperties;
- }
-
- /**
- * Allows for custom web security rules to be applied.
- *
- * @param http {@link HttpSecurity} for configuring web based security
- * @throws Exception
- */
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- List matchersToBypass = new ArrayList<>(List.of("/actuator/**", "/metrics/**"));
-
- if (feastProperties.securityProperties().isDisableRestControllerAuth()) {
- matchersToBypass.add("/api/v1/**");
- matchersToBypass.add("/api/v2/**");
- }
-
- // Bypasses security/authentication for the following paths
- http.authorizeRequests()
- .antMatchers(matchersToBypass.toArray(new String[0]))
- .permitAll()
- .anyRequest()
- .authenticated()
- .and()
- .csrf()
- .disable();
- }
-}
diff --git a/core/src/main/java/feast/core/controller/CoreServiceRestController.java b/core/src/main/java/feast/core/controller/CoreServiceRestController.java
deleted file mode 100644
index f782c172cd6..00000000000
--- a/core/src/main/java/feast/core/controller/CoreServiceRestController.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2019 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.core.controller;
-
-import feast.core.config.FeastProperties;
-import feast.core.model.Project;
-import feast.core.service.ProjectService;
-import feast.core.service.SpecService;
-import feast.proto.core.CoreServiceProto.GetFeastCoreVersionResponse;
-import feast.proto.core.CoreServiceProto.ListEntitiesRequest;
-import feast.proto.core.CoreServiceProto.ListEntitiesResponse;
-import feast.proto.core.CoreServiceProto.ListFeatureTablesRequest;
-import feast.proto.core.CoreServiceProto.ListFeatureTablesResponse;
-import feast.proto.core.CoreServiceProto.ListFeaturesRequest;
-import feast.proto.core.CoreServiceProto.ListFeaturesResponse;
-import feast.proto.core.CoreServiceProto.ListProjectsResponse;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * EXPERIMENTAL: Controller for HTTP endpoints to Feast Core. These endpoints are subject to change.
- */
-@RestController
-@CrossOrigin
-@Slf4j
-@RequestMapping(value = "/api", produces = "application/json")
-public class CoreServiceRestController {
-
- private final FeastProperties feastProperties;
- private SpecService specService;
- private ProjectService projectService;
-
- @Autowired
- public CoreServiceRestController(
- FeastProperties feastProperties, SpecService specService, ProjectService projectService) {
- this.feastProperties = feastProperties;
- this.specService = specService;
- this.projectService = projectService;
- }
-
- /**
- * GET /version : Fetches the version of Feast Core.
- *
- * @return (200 OK) Returns {@link GetFeastCoreVersionResponse} in JSON.
- */
- @RequestMapping(value = "/v2/version", method = RequestMethod.GET)
- public GetFeastCoreVersionResponse getVersion() {
- GetFeastCoreVersionResponse response =
- GetFeastCoreVersionResponse.newBuilder().setVersion(feastProperties.getVersion()).build();
- return response;
- }
-
- /**
- * GET /features : List Features based on project and entities.
- *
- * @param entities Request Parameter: List of all entities every returned feature should belong
- * to. At least one entity is required. For example, if entity1 and entity2
- * are given, then all features returned (if any) will belong to BOTH
- * entities.
- * @param project (Optional) Request Parameter: A single project where the feature table of all
- * features returned is under. If not provided, the default project will be used, usually
- * default.
- * @return (200 OK) Return {@link ListFeaturesResponse} in JSON.
- */
- @RequestMapping(value = "/v2/features", method = RequestMethod.GET)
- public ListFeaturesResponse listFeatures(
- @RequestParam String[] entities, @RequestParam(required = false) Optional project) {
- ListFeaturesRequest.Filter.Builder filterBuilder =
- ListFeaturesRequest.Filter.newBuilder().addAllEntities(Arrays.asList(entities));
- project.ifPresent(filterBuilder::setProject);
- return specService.listFeatures(filterBuilder.build());
- }
-
- /**
- * GET /projects : Get the list of existing feast projects.
- *
- * @return (200 OK) Returns {@link ListProjectsResponse} in JSON.
- */
- @RequestMapping(value = "/v2/projects", method = RequestMethod.GET)
- public ListProjectsResponse listProjects() {
- List projects = projectService.listProjects();
- return ListProjectsResponse.newBuilder()
- .addAllProjects(projects.stream().map(Project::getName).collect(Collectors.toList()))
- .build();
- }
-
- /**
- * GET /entities : Retrieve a list of Entities according to filtering parameters of Feast project
- * name. If none matches, an empty JSON response is returned.
- *
- * @param project Request Parameter: Name of feast project to search in.
- * @return (200 OK) Return {@link ListEntitiesResponse} in JSON.
- */
- @RequestMapping(value = "/v2/entities", method = RequestMethod.GET)
- public ListEntitiesResponse listEntities(
- @RequestParam(defaultValue = Project.DEFAULT_NAME) String project) {
- ListEntitiesRequest.Filter.Builder filterBuilder =
- ListEntitiesRequest.Filter.newBuilder().setProject(project);
- return specService.listEntities(filterBuilder.build());
- }
-
- /**
- * GET /feature-tables : Retrieve a list of Feature Tables according to filtering parameters of
- * Feast project name. If none matches, an empty JSON response is returned.
- *
- * @param project Request Parameter: Name of feast project to search in.
- * @return (200 OK) Return {@link ListFeatureTablesResponse} in JSON.
- */
- @RequestMapping(value = "/v2/feature-tables", method = RequestMethod.GET)
- public ListFeatureTablesResponse listFeatureTables(
- @RequestParam(defaultValue = Project.DEFAULT_NAME) String project) {
- ListFeatureTablesRequest.Filter.Builder filterBuilder =
- ListFeatureTablesRequest.Filter.newBuilder().setProject(project);
- return specService.listFeatureTables(filterBuilder.build());
- }
-}
diff --git a/core/src/main/java/feast/core/controller/exception/handler/RestResponseEntityExceptionHandler.java b/core/src/main/java/feast/core/controller/exception/handler/RestResponseEntityExceptionHandler.java
deleted file mode 100644
index ef27e4aee8a..00000000000
--- a/core/src/main/java/feast/core/controller/exception/handler/RestResponseEntityExceptionHandler.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- * Copyright 2018-2020 The Feast Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package feast.core.controller.exception.handler;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-import feast.core.exception.RetrievalException;
-import java.util.Map;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.MissingServletRequestParameterException;
-import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.context.request.WebRequest;
-import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
-
-/** A exception handler for some common exceptions while accessing Feast Core via HTTP. */
-@ControllerAdvice
-public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
-
- /**
- * Handles the case when a request object (such as {@link
- * feast.proto.core.CoreServiceProto.GetFeatureTableRequest}) or a response object (such as {@link
- * feast.proto.core.CoreServiceProto.GetFeatureTableResponse} is malformed.
- *
- * @param ex the {@link InvalidProtocolBufferException} that occurred.
- * @param request the {@link WebRequest} that caused this exception.
- * @return (500 Internal Server Error)
- */
- @ExceptionHandler({InvalidProtocolBufferException.class})
- protected ResponseEntity