Skip to content

Commit 57b04ff

Browse files
committed
[HWORKS-981] Resource endpoints should be defined only in final classes (#1707)
1 parent 92a0373 commit 57b04ff

15 files changed

+1194
-690
lines changed

hopsworks-api/src/main/java/io/hops/hopsworks/api/featurestore/featuregroup/FeaturegroupService.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package io.hops.hopsworks.api.featurestore.featuregroup;
1818

1919
import com.google.common.base.Strings;
20-
import io.hops.hopsworks.api.featurestore.FeaturestoreKeywordResource;
2120
import io.hops.hopsworks.api.featurestore.activities.ActivityResource;
2221
import io.hops.hopsworks.api.featurestore.code.CodeResource;
2322
import io.hops.hopsworks.api.featurestore.commit.CommitResource;
@@ -26,6 +25,7 @@
2625
import io.hops.hopsworks.api.featurestore.datavalidationv2.reports.ValidationReportResource;
2726
import io.hops.hopsworks.api.featurestore.datavalidationv2.results.ValidationResultResource;
2827
import io.hops.hopsworks.api.featurestore.datavalidationv2.suites.ExpectationSuiteResource;
28+
import io.hops.hopsworks.api.featurestore.keyword.FeatureGroupKeywordResource;
2929
import io.hops.hopsworks.api.featurestore.statistics.StatisticsResource;
3030
import io.hops.hopsworks.api.featurestore.tag.FeatureGroupTagResource;
3131
import io.hops.hopsworks.api.filter.JWTNotRequired;
@@ -132,7 +132,7 @@ public class FeaturegroupService {
132132
@Inject
133133
private IngestionJobBuilder ingestionJobBuilder;
134134
@Inject
135-
private FeaturestoreKeywordResource featurestoreKeywordResource;
135+
private FeatureGroupKeywordResource featureGroupKeywordResource;
136136
@Inject
137137
private ActivityResource activityResource;
138138
@Inject
@@ -646,13 +646,13 @@ public CommitResource timetravel (
646646

647647

648648
@Path("/{featureGroupId}/keywords")
649-
public FeaturestoreKeywordResource keywords (
649+
public FeatureGroupKeywordResource keywords (
650650
@ApiParam(value = "Id of the featuregroup") @PathParam("featureGroupId") Integer featureGroupId)
651651
throws FeaturestoreException {
652-
this.featurestoreKeywordResource.setProject(project);
653-
this.featurestoreKeywordResource.setFeaturestore(featurestore);
654-
this.featurestoreKeywordResource.setFeatureGroupId(featureGroupId);
655-
return featurestoreKeywordResource;
652+
this.featureGroupKeywordResource.setProject(project);
653+
this.featureGroupKeywordResource.setFeaturestore(featurestore);
654+
this.featureGroupKeywordResource.setFeatureGroupId(featureGroupId);
655+
return featureGroupKeywordResource;
656656
}
657657

658658
@Path("/{featureGroupId}/activity")

hopsworks-api/src/main/java/io/hops/hopsworks/api/featurestore/featureview/FeatureViewService.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

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

19-
import io.hops.hopsworks.api.featurestore.FeaturestoreKeywordResource;
2019
import io.hops.hopsworks.api.featurestore.activities.ActivityResource;
20+
import io.hops.hopsworks.api.featurestore.keyword.FeatureViewKeywordResource;
2121
import io.hops.hopsworks.api.featurestore.preparestatement.PreparedStatementResource;
2222
import io.hops.hopsworks.api.featurestore.query.QueryResource;
2323
import io.hops.hopsworks.api.featurestore.statistics.StatisticsResource;
@@ -61,7 +61,7 @@ public class FeatureViewService {
6161
@Inject
6262
private PreparedStatementResource preparedStatementResource;
6363
@Inject
64-
private FeaturestoreKeywordResource featurestoreKeywordResource;
64+
private FeatureViewKeywordResource featureViewKeywordResource;
6565
@EJB
6666
private FeaturestoreController featurestoreController;
6767
@Inject
@@ -120,18 +120,18 @@ public QueryResource query(
120120
}
121121

122122
@Path("/{name: [a-z0-9_]*(?=[a-z])[a-z0-9_]+}/version/{version: [0-9]+}/keywords")
123-
public FeaturestoreKeywordResource keywords(
123+
public FeatureViewKeywordResource keywords(
124124
@ApiParam(value = "Name of the feature view", required = true)
125125
@PathParam("name")
126126
String featureViewName,
127127
@ApiParam(value = "Version of the feature view", required = true)
128128
@PathParam("version")
129129
Integer version
130130
) throws FeaturestoreException {
131-
this.featurestoreKeywordResource.setProject(project);
132-
this.featurestoreKeywordResource.setFeaturestore(featurestore);
133-
this.featurestoreKeywordResource.setFeatureView(featureViewName, version);
134-
return this.featurestoreKeywordResource;
131+
this.featureViewKeywordResource.setProject(project);
132+
this.featureViewKeywordResource.setFeaturestore(featurestore);
133+
this.featureViewKeywordResource.setFeatureView(featureViewName, version);
134+
return this.featureViewKeywordResource;
135135
}
136136

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

17-
package io.hops.hopsworks.api.featurestore;
18-
19-
import io.hops.hopsworks.common.featurestore.featureview.FeatureViewController;
18+
import io.hops.hopsworks.api.auth.key.ApiKeyRequired;
19+
import io.hops.hopsworks.api.featurestore.FeaturestoreKeywordBuilder;
2020
import io.hops.hopsworks.api.filter.AllowedProjectRoles;
2121
import io.hops.hopsworks.api.filter.Audience;
22-
import io.hops.hopsworks.api.auth.key.ApiKeyRequired;
2322
import io.hops.hopsworks.common.api.ResourceRequest;
2423
import io.hops.hopsworks.common.featurestore.featuregroup.FeaturegroupController;
2524
import io.hops.hopsworks.common.featurestore.keyword.KeywordDTO;
@@ -28,11 +27,8 @@
2827
import io.hops.hopsworks.jwt.annotation.JWTRequired;
2928
import io.hops.hopsworks.persistence.entity.featurestore.Featurestore;
3029
import io.hops.hopsworks.persistence.entity.featurestore.featuregroup.Featuregroup;
31-
import io.hops.hopsworks.persistence.entity.featurestore.featureview.FeatureView;
32-
import io.hops.hopsworks.persistence.entity.featurestore.trainingdataset.TrainingDataset;
3330
import io.hops.hopsworks.persistence.entity.project.Project;
3431
import io.hops.hopsworks.persistence.entity.user.security.apiKey.ApiScope;
35-
import io.hops.hopsworks.restutils.RESTCodes;
3632
import io.swagger.annotations.Api;
3733
import io.swagger.annotations.ApiOperation;
3834

@@ -55,27 +51,21 @@
5551
import javax.ws.rs.core.UriInfo;
5652
import java.util.HashSet;
5753
import java.util.List;
58-
import java.util.logging.Level;
5954

6055
@RequestScoped
6156
@TransactionAttribute(TransactionAttributeType.NEVER)
62-
@Api(value = "Feature store labels resource")
63-
public class FeaturestoreKeywordResource {
64-
57+
@Api(value = "Feature Group Keywords Resource")
58+
public class FeatureGroupKeywordResource {
6559
@EJB
6660
private FeaturegroupController featuregroupController;
6761
@EJB
68-
private FeatureViewController featureViewController;
69-
@EJB
7062
private FeaturestoreKeywordBuilder featurestoreKeywordBuilder;
7163
@Inject
7264
private FeatureStoreKeywordControllerIface keywordCtrl;
7365

7466
private Project project;
7567
private Featurestore featurestore;
7668
private Featuregroup featuregroup;
77-
private TrainingDataset trainingDataset;
78-
private FeatureView featureView;
7969

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

92-
public void setTrainingDataset(TrainingDataset trainingDataset) {
93-
this.trainingDataset = trainingDataset;
94-
}
95-
96-
public void setFeatureView(String name, Integer version) throws FeaturestoreException {
97-
this.featureView = featureViewController.getByNameVersionAndFeatureStore(name, version, featurestore);
98-
}
99-
10082
@GET
10183
@Produces(MediaType.APPLICATION_JSON)
10284
@ApiOperation(value = "Get keywords")
10385
@AllowedProjectRoles({AllowedProjectRoles.DATA_OWNER, AllowedProjectRoles.DATA_SCIENTIST})
10486
@JWTRequired(acceptedTokens = {Audience.API, Audience.JOB},
105-
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
87+
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
10688
@ApiKeyRequired(acceptedScopes = {ApiScope.FEATURESTORE},
107-
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
89+
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
10890
public Response getKeywords(@Context SecurityContext sc,
10991
@Context HttpServletRequest req,
110-
@Context UriInfo uriInfo)
111-
throws FeaturestoreException {
112-
92+
@Context UriInfo uriInfo) {
11393
ResourceRequest resourceRequest = new ResourceRequest(ResourceRequest.Name.KEYWORDS);
114-
KeywordDTO dto;
115-
if (featuregroup != null) {
116-
List<String> keywords = keywordCtrl.getKeywords(featuregroup);
117-
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, keywords);
118-
} else if (trainingDataset != null) {
119-
List<String> keywords = keywordCtrl.getKeywords(trainingDataset);
120-
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, trainingDataset, keywords);
121-
} else if (featureView != null) {
122-
List<String> keywords = keywordCtrl.getKeywords(featureView);
123-
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featureView, keywords);
124-
} else {
125-
throw new FeaturestoreException(RESTCodes.FeaturestoreErrorCode.KEYWORD_ERROR, Level.FINE,
126-
"Error building keyword object");
127-
}
94+
List<String> keywords = keywordCtrl.getKeywords(featuregroup);
95+
KeywordDTO dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, keywords);
12896
return Response.ok().entity(dto).build();
12997
}
13098

@@ -134,64 +102,36 @@ public Response getKeywords(@Context SecurityContext sc,
134102
@ApiOperation(value = "Create keywords or replace existing ones")
135103
@AllowedProjectRoles({AllowedProjectRoles.DATA_OWNER})
136104
@JWTRequired(acceptedTokens = {Audience.API, Audience.JOB},
137-
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
105+
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
138106
@ApiKeyRequired(acceptedScopes = {ApiScope.FEATURESTORE},
139-
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
107+
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
140108
public Response replaceKeywords(@Context SecurityContext sc,
141109
@Context HttpServletRequest req,
142110
@Context UriInfo uriInfo, KeywordDTO keywordDTO)
143111
throws FeaturestoreException {
144112
ResourceRequest resourceRequest = new ResourceRequest(ResourceRequest.Name.KEYWORDS);
145113
KeywordDTO dto;
146-
if (featuregroup != null) {
147-
List<String> updatedKeywords = keywordCtrl.replaceKeywords(featuregroup,
148-
new HashSet<>(keywordDTO.getKeywords()));
149-
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, updatedKeywords);
150-
} else if (trainingDataset != null) {
151-
List<String> updatedKeywords = keywordCtrl.replaceKeywords(trainingDataset,
152-
new HashSet<>(keywordDTO.getKeywords()));
153-
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, trainingDataset, updatedKeywords);
154-
} else if (featureView != null) {
155-
List<String> updatedKeywords = keywordCtrl.replaceKeywords(featureView,
156-
new HashSet<>(keywordDTO.getKeywords()));
157-
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featureView, updatedKeywords);
158-
} else {
159-
throw new FeaturestoreException(RESTCodes.FeaturestoreErrorCode.KEYWORD_ERROR, Level.FINE,
160-
"Error building keyword object");
161-
}
114+
List<String> updatedKeywords = keywordCtrl.replaceKeywords(featuregroup, new HashSet<>(keywordDTO.getKeywords()));
115+
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, updatedKeywords);
162116
return Response.ok().entity(dto).build();
163117
}
164118

165119
@DELETE
166120
@ApiOperation(value = "Delete a keyword")
167121
@AllowedProjectRoles({AllowedProjectRoles.DATA_OWNER})
168122
@JWTRequired(acceptedTokens = {Audience.API, Audience.JOB},
169-
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
123+
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
170124
@ApiKeyRequired(acceptedScopes = {ApiScope.FEATURESTORE},
171-
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
125+
allowedUserRoles = {"HOPS_ADMIN", "HOPS_USER", "HOPS_SERVICE_USER"})
172126
public Response deleteKeywords(@Context SecurityContext sc,
173127
@Context UriInfo uriInfo,
174128
@Context HttpServletRequest req,
175129
@QueryParam("keyword") String keyword)
176130
throws FeaturestoreException {
177131
ResourceRequest resourceRequest = new ResourceRequest(ResourceRequest.Name.KEYWORDS);
178-
KeywordDTO dto;
179-
if (featuregroup != null) {
180-
keywordCtrl.deleteKeyword(featuregroup, keyword);
181-
List<String> updatedKeywords = keywordCtrl.getKeywords(featuregroup);
182-
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, updatedKeywords);
183-
} else if (trainingDataset != null) {
184-
keywordCtrl.deleteKeyword(trainingDataset, keyword);
185-
List<String> updatedKeywords = keywordCtrl.getKeywords(trainingDataset);
186-
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, trainingDataset, updatedKeywords);
187-
} else if (featureView != null) {
188-
keywordCtrl.deleteKeyword(featureView, keyword);
189-
List<String> updatedKeywords = keywordCtrl.getKeywords(featureView);
190-
dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featureView, updatedKeywords);
191-
} else {
192-
throw new FeaturestoreException(RESTCodes.FeaturestoreErrorCode.KEYWORD_ERROR, Level.FINE,
193-
"Error building keyword object");
194-
}
132+
keywordCtrl.deleteKeyword(featuregroup, keyword);
133+
List<String> updatedKeywords = keywordCtrl.getKeywords(featuregroup);
134+
KeywordDTO dto = featurestoreKeywordBuilder.build(uriInfo, resourceRequest, project, featuregroup, updatedKeywords);
195135
return Response.ok().entity(dto).build();
196136
}
197137
}

0 commit comments

Comments
 (0)