Skip to content

Commit

Permalink
[HWORKS-981] Resource endpoints should be defined only in final class…
Browse files Browse the repository at this point in the history
…es (#1707)
  • Loading branch information
o-alex committed Feb 13, 2024
1 parent 92a0373 commit 57b04ff
Show file tree
Hide file tree
Showing 15 changed files with 1,194 additions and 690 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package io.hops.hopsworks.api.featurestore.featuregroup;

import com.google.common.base.Strings;
import io.hops.hopsworks.api.featurestore.FeaturestoreKeywordResource;
import io.hops.hopsworks.api.featurestore.activities.ActivityResource;
import io.hops.hopsworks.api.featurestore.code.CodeResource;
import io.hops.hopsworks.api.featurestore.commit.CommitResource;
Expand All @@ -26,6 +25,7 @@
import io.hops.hopsworks.api.featurestore.datavalidationv2.reports.ValidationReportResource;
import io.hops.hopsworks.api.featurestore.datavalidationv2.results.ValidationResultResource;
import io.hops.hopsworks.api.featurestore.datavalidationv2.suites.ExpectationSuiteResource;
import io.hops.hopsworks.api.featurestore.keyword.FeatureGroupKeywordResource;
import io.hops.hopsworks.api.featurestore.statistics.StatisticsResource;
import io.hops.hopsworks.api.featurestore.tag.FeatureGroupTagResource;
import io.hops.hopsworks.api.filter.JWTNotRequired;
Expand Down Expand Up @@ -132,7 +132,7 @@ public class FeaturegroupService {
@Inject
private IngestionJobBuilder ingestionJobBuilder;
@Inject
private FeaturestoreKeywordResource featurestoreKeywordResource;
private FeatureGroupKeywordResource featureGroupKeywordResource;
@Inject
private ActivityResource activityResource;
@Inject
Expand Down Expand Up @@ -646,13 +646,13 @@ public CommitResource timetravel (


@Path("/{featureGroupId}/keywords")
public FeaturestoreKeywordResource keywords (
public FeatureGroupKeywordResource keywords (
@ApiParam(value = "Id of the featuregroup") @PathParam("featureGroupId") Integer featureGroupId)
throws FeaturestoreException {
this.featurestoreKeywordResource.setProject(project);
this.featurestoreKeywordResource.setFeaturestore(featurestore);
this.featurestoreKeywordResource.setFeatureGroupId(featureGroupId);
return featurestoreKeywordResource;
this.featureGroupKeywordResource.setProject(project);
this.featureGroupKeywordResource.setFeaturestore(featurestore);
this.featureGroupKeywordResource.setFeatureGroupId(featureGroupId);
return featureGroupKeywordResource;
}

@Path("/{featureGroupId}/activity")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

package io.hops.hopsworks.api.featurestore.featureview;

import io.hops.hopsworks.api.featurestore.FeaturestoreKeywordResource;
import io.hops.hopsworks.api.featurestore.activities.ActivityResource;
import io.hops.hopsworks.api.featurestore.keyword.FeatureViewKeywordResource;
import io.hops.hopsworks.api.featurestore.preparestatement.PreparedStatementResource;
import io.hops.hopsworks.api.featurestore.query.QueryResource;
import io.hops.hopsworks.api.featurestore.statistics.StatisticsResource;
Expand Down Expand Up @@ -61,7 +61,7 @@ public class FeatureViewService {
@Inject
private PreparedStatementResource preparedStatementResource;
@Inject
private FeaturestoreKeywordResource featurestoreKeywordResource;
private FeatureViewKeywordResource featureViewKeywordResource;
@EJB
private FeaturestoreController featurestoreController;
@Inject
Expand Down Expand Up @@ -120,18 +120,18 @@ public QueryResource query(
}

@Path("/{name: [a-z0-9_]*(?=[a-z])[a-z0-9_]+}/version/{version: [0-9]+}/keywords")
public FeaturestoreKeywordResource keywords(
public FeatureViewKeywordResource keywords(
@ApiParam(value = "Name of the feature view", required = true)
@PathParam("name")
String featureViewName,
@ApiParam(value = "Version of the feature view", required = true)
@PathParam("version")
Integer version
) throws FeaturestoreException {
this.featurestoreKeywordResource.setProject(project);
this.featurestoreKeywordResource.setFeaturestore(featurestore);
this.featurestoreKeywordResource.setFeatureView(featureViewName, version);
return this.featurestoreKeywordResource;
this.featureViewKeywordResource.setProject(project);
this.featureViewKeywordResource.setFeaturestore(featurestore);
this.featureViewKeywordResource.setFeatureView(featureViewName, version);
return this.featureViewKeywordResource;
}

@Path("/{name: [a-z0-9_]*(?=[a-z])[a-z0-9_]+}/version/{version: [0-9]+}/activity")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* This file is part of Hopsworks
* Copyright (C) 2020, Logical Clocks AB. All rights reserved
* Copyright (C) 2024, Hopsworks AB. All rights reserved
*
* Hopsworks is free software: you can redistribute it and/or modify it under the terms of
* the GNU Affero General Public License as published by the Free Software Foundation,
Expand All @@ -13,13 +13,12 @@
* You should have received a copy of the GNU Affero General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
package io.hops.hopsworks.api.featurestore.keyword;

package io.hops.hopsworks.api.featurestore;

import io.hops.hopsworks.common.featurestore.featureview.FeatureViewController;
import io.hops.hopsworks.api.auth.key.ApiKeyRequired;
import io.hops.hopsworks.api.featurestore.FeaturestoreKeywordBuilder;
import io.hops.hopsworks.api.filter.AllowedProjectRoles;
import io.hops.hopsworks.api.filter.Audience;
import io.hops.hopsworks.api.auth.key.ApiKeyRequired;
import io.hops.hopsworks.common.api.ResourceRequest;
import io.hops.hopsworks.common.featurestore.featuregroup.FeaturegroupController;
import io.hops.hopsworks.common.featurestore.keyword.KeywordDTO;
Expand All @@ -28,11 +27,8 @@
import io.hops.hopsworks.jwt.annotation.JWTRequired;
import io.hops.hopsworks.persistence.entity.featurestore.Featurestore;
import io.hops.hopsworks.persistence.entity.featurestore.featuregroup.Featuregroup;
import io.hops.hopsworks.persistence.entity.featurestore.featureview.FeatureView;
import io.hops.hopsworks.persistence.entity.featurestore.trainingdataset.TrainingDataset;
import io.hops.hopsworks.persistence.entity.project.Project;
import io.hops.hopsworks.persistence.entity.user.security.apiKey.ApiScope;
import io.hops.hopsworks.restutils.RESTCodes;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

Expand All @@ -55,27 +51,21 @@
import javax.ws.rs.core.UriInfo;
import java.util.HashSet;
import java.util.List;
import java.util.logging.Level;

@RequestScoped
@TransactionAttribute(TransactionAttributeType.NEVER)
@Api(value = "Feature store labels resource")
public class FeaturestoreKeywordResource {

@Api(value = "Feature Group Keywords Resource")
public class FeatureGroupKeywordResource {
@EJB
private FeaturegroupController featuregroupController;
@EJB
private FeatureViewController featureViewController;
@EJB
private FeaturestoreKeywordBuilder featurestoreKeywordBuilder;
@Inject
private FeatureStoreKeywordControllerIface keywordCtrl;

private Project project;
private Featurestore featurestore;
private Featuregroup featuregroup;
private TrainingDataset trainingDataset;
private FeatureView featureView;

public void setProject(Project project) {
this.project = project;
Expand All @@ -89,42 +79,20 @@ public void setFeatureGroupId(Integer featureGroupId) throws FeaturestoreExcepti
this.featuregroup = featuregroupController.getFeaturegroupById(featurestore, featureGroupId);
}

public void setTrainingDataset(TrainingDataset trainingDataset) {
this.trainingDataset = trainingDataset;
}

public void setFeatureView(String name, Integer version) throws FeaturestoreException {
this.featureView = featureViewController.getByNameVersionAndFeatureStore(name, version, featurestore);
}

@GET
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Get keywords")
@AllowedProjectRoles({AllowedProjectRoles.DATA_OWNER, AllowedProjectRoles.DATA_SCIENTIST})
@JWTRequired(acceptedTokens = {Audience.API, Audience.JOB},
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
@ApiKeyRequired(acceptedScopes = {ApiScope.FEATURESTORE},
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
public Response getKeywords(@Context SecurityContext sc,
@Context HttpServletRequest req,
@Context UriInfo uriInfo)
throws FeaturestoreException {

@Context UriInfo uriInfo) {
ResourceRequest resourceRequest = new ResourceRequest(ResourceRequest.Name.KEYWORDS);
KeywordDTO dto;
if (featuregroup != null) {
List<String> keywords = keywordCtrl.getKeywords(featuregroup);
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, keywords);
} else if (trainingDataset != null) {
List<String> keywords = keywordCtrl.getKeywords(trainingDataset);
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, trainingDataset, keywords);
} else if (featureView != null) {
List<String> keywords = keywordCtrl.getKeywords(featureView);
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featureView, keywords);
} else {
throw new FeaturestoreException(RESTCodes.FeaturestoreErrorCode.KEYWORD_ERROR, Level.FINE,
"Error building keyword object");
}
List<String> keywords = keywordCtrl.getKeywords(featuregroup);
KeywordDTO dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, keywords);
return Response.ok().entity(dto).build();
}

Expand All @@ -134,64 +102,36 @@ public Response getKeywords(@Context SecurityContext sc,
@ApiOperation(value = "Create keywords or replace existing ones")
@AllowedProjectRoles({AllowedProjectRoles.DATA_OWNER})
@JWTRequired(acceptedTokens = {Audience.API, Audience.JOB},
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
@ApiKeyRequired(acceptedScopes = {ApiScope.FEATURESTORE},
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
public Response replaceKeywords(@Context SecurityContext sc,
@Context HttpServletRequest req,
@Context UriInfo uriInfo, KeywordDTO keywordDTO)
throws FeaturestoreException {
ResourceRequest resourceRequest = new ResourceRequest(ResourceRequest.Name.KEYWORDS);
KeywordDTO dto;
if (featuregroup != null) {
List<String> updatedKeywords = keywordCtrl.replaceKeywords(featuregroup,
new HashSet<>(keywordDTO.getKeywords()));
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, updatedKeywords);
} else if (trainingDataset != null) {
List<String> updatedKeywords = keywordCtrl.replaceKeywords(trainingDataset,
new HashSet<>(keywordDTO.getKeywords()));
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, trainingDataset, updatedKeywords);
} else if (featureView != null) {
List<String> updatedKeywords = keywordCtrl.replaceKeywords(featureView,
new HashSet<>(keywordDTO.getKeywords()));
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featureView, updatedKeywords);
} else {
throw new FeaturestoreException(RESTCodes.FeaturestoreErrorCode.KEYWORD_ERROR, Level.FINE,
"Error building keyword object");
}
List<String> updatedKeywords = keywordCtrl.replaceKeywords(featuregroup, new HashSet<>(keywordDTO.getKeywords()));
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, updatedKeywords);
return Response.ok().entity(dto).build();
}

@DELETE
@ApiOperation(value = "Delete a keyword")
@AllowedProjectRoles({AllowedProjectRoles.DATA_OWNER})
@JWTRequired(acceptedTokens = {Audience.API, Audience.JOB},
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
@ApiKeyRequired(acceptedScopes = {ApiScope.FEATURESTORE},
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
public Response deleteKeywords(@Context SecurityContext sc,
@Context UriInfo uriInfo,
@Context HttpServletRequest req,
@QueryParam("keyword") String keyword)
throws FeaturestoreException {
ResourceRequest resourceRequest = new ResourceRequest(ResourceRequest.Name.KEYWORDS);
KeywordDTO dto;
if (featuregroup != null) {
keywordCtrl.deleteKeyword(featuregroup, keyword);
List<String> updatedKeywords = keywordCtrl.getKeywords(featuregroup);
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, updatedKeywords);
} else if (trainingDataset != null) {
keywordCtrl.deleteKeyword(trainingDataset, keyword);
List<String> updatedKeywords = keywordCtrl.getKeywords(trainingDataset);
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, trainingDataset, updatedKeywords);
} else if (featureView != null) {
keywordCtrl.deleteKeyword(featureView, keyword);
List<String> updatedKeywords = keywordCtrl.getKeywords(featureView);
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featureView, updatedKeywords);
} else {
throw new FeaturestoreException(RESTCodes.FeaturestoreErrorCode.KEYWORD_ERROR, Level.FINE,
"Error building keyword object");
}
keywordCtrl.deleteKeyword(featuregroup, keyword);
List<String> updatedKeywords = keywordCtrl.getKeywords(featuregroup);
KeywordDTO dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, updatedKeywords);
return Response.ok().entity(dto).build();
}
}
Loading

0 comments on commit 57b04ff

Please sign in to comment.