diff --git a/core/src/main/java/feast/core/service/SpecService.java b/core/src/main/java/feast/core/service/SpecService.java index 5b98d065977..8fec6ac5112 100644 --- a/core/src/main/java/feast/core/service/SpecService.java +++ b/core/src/main/java/feast/core/service/SpecService.java @@ -288,19 +288,14 @@ public ApplyFeatureSetResponse applyFeatureSet(FeatureSetProto.FeatureSet newFea // Validate incoming feature set FeatureSetValidator.validateSpec(newFeatureSet); - // Ensure that the project already exists + // Find project or create new one if it does not exist String project_name = newFeatureSet.getSpec().getProject(); Project project = projectRepository .findById(newFeatureSet.getSpec().getProject()) - .orElseThrow( - () -> - new IllegalArgumentException( - String.format( - "Project name does not exist. Please create a project first: %s", - project_name))); - - // Ensure that the project is not archived + .orElse(new Project(project_name)); + + // Ensure that the project retrieved from repository is not archived if (project.isArchived()) { throw new IllegalArgumentException(String.format("Project is archived: %s", project_name)); } diff --git a/core/src/test/java/feast/core/service/SpecServiceTest.java b/core/src/test/java/feast/core/service/SpecServiceTest.java index 1eb56caac26..43a66135dce 100644 --- a/core/src/test/java/feast/core/service/SpecServiceTest.java +++ b/core/src/test/java/feast/core/service/SpecServiceTest.java @@ -170,6 +170,10 @@ public void setUp() { when(projectRepository.findAllByArchivedIsFalse()) .thenReturn(Collections.singletonList(new Project("project1"))); when(projectRepository.findById("project1")).thenReturn(Optional.of(new Project("project1"))); + Project archivedProject = new Project("archivedproject"); + archivedProject.setArchived(true); + when(projectRepository.findById(archivedProject.getName())) + .thenReturn(Optional.of(archivedProject)); Store store1 = newDummyStore("SERVING"); Store store2 = newDummyStore("WAREHOUSE"); @@ -706,6 +710,55 @@ public void applyFeatureSetShouldUpdateFeatureSetWhenConstraintsAreUpdated() } } + @Test + public void applyFeatureSetShouldCreateProjectWhenNotAlreadyExists() + throws InvalidProtocolBufferException { + Field f3f1 = new Field("f3f1", Enum.INT64); + Field f3f2 = new Field("f3f2", Enum.INT64); + Field f3e1 = new Field("f3e1", Enum.STRING); + FeatureSetProto.FeatureSet incomingFeatureSet = + (new FeatureSet( + "f3", + "newproject", + 5, + 100L, + Arrays.asList(f3e1), + Arrays.asList(f3f2, f3f1), + defaultSource, + FeatureSetStatus.STATUS_READY)) + .toProto(); + + ApplyFeatureSetResponse applyFeatureSetResponse = + specService.applyFeatureSet(incomingFeatureSet); + assertThat(applyFeatureSetResponse.getStatus(), equalTo(Status.CREATED)); + assertThat( + applyFeatureSetResponse.getFeatureSet().getSpec().getProject(), + equalTo(incomingFeatureSet.getSpec().getProject())); + } + + @Test + public void applyFeatureSetShouldFailWhenProjectIsArchived() + throws InvalidProtocolBufferException { + Field f3f1 = new Field("f3f1", Enum.INT64); + Field f3f2 = new Field("f3f2", Enum.INT64); + Field f3e1 = new Field("f3e1", Enum.STRING); + FeatureSetProto.FeatureSet incomingFeatureSet = + (new FeatureSet( + "f3", + "archivedproject", + 5, + 100L, + Arrays.asList(f3e1), + Arrays.asList(f3f2, f3f1), + defaultSource, + FeatureSetStatus.STATUS_READY)) + .toProto(); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Project is archived"); + specService.applyFeatureSet(incomingFeatureSet); + } + @Test public void shouldUpdateStoreIfConfigChanges() throws InvalidProtocolBufferException { when(storeRepository.findById("SERVING")).thenReturn(Optional.of(stores.get(0)));