Remove getById, getByName, list operations implementation and use from EntityRepository

This commit is contained in:
sureshms 2021-10-22 07:00:14 -07:00
parent dcf8aaa4eb
commit ad8210e286
20 changed files with 68 additions and 269 deletions

View File

@ -46,21 +46,6 @@ public class DashboardServiceRepositoryHelper extends EntityRepository<Dashboard
this.repo3 = repo3;
}
@Transaction
public List<DashboardService> list(String name) throws IOException {
return JsonUtils.readObjects(repo3.dashboardServiceDAO().list(name), DashboardService.class);
}
@Transaction
public DashboardService get(String id) throws IOException {
return repo3.dashboardServiceDAO().findEntityById(id);
}
@Transaction
public DashboardService getByName(String name) throws IOException {
return repo3.dashboardServiceDAO().findEntityByName(name);
}
@Transaction
public DashboardService create(DashboardService dashboardService) throws JsonProcessingException {
// Validate fields

View File

@ -1,13 +1,8 @@
package org.openmetadata.catalog.jdbi3;
import org.jdbi.v3.sqlobject.customizer.Bind;
import org.jdbi.v3.sqlobject.customizer.Define;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.openmetadata.catalog.entity.services.DatabaseService;
import java.util.List;
public interface DatabaseServiceDAO3 extends EntityDAO<DatabaseService> {
@Override
default String getTableName() { return "dbService_Entity"; }
@ -17,8 +12,4 @@ public interface DatabaseServiceDAO3 extends EntityDAO<DatabaseService> {
@Override
default String getNameColumn() { return "name"; }
// TODO clean this up
@SqlQuery("SELECT json FROM dbService_Entity WHERE (name = :name OR :name is NULL)")
List<String> list(@Bind("name") String name);
}

View File

@ -46,22 +46,6 @@ public class DatabaseServiceRepositoryHelper extends EntityRepository<DatabaseSe
this.repo3 = repo3;
}
@Transaction
public List<DatabaseService> list(String name) throws IOException {
return JsonUtils.readObjects(repo3.dbServiceDAO().list(name), DatabaseService.class);
}
@Transaction
public DatabaseService get(String id) throws IOException {
return repo3.dbServiceDAO().findEntityById(id);
}
@Transaction
public DatabaseService getByName(String name) throws IOException {
return repo3.dbServiceDAO().findEntityByName(name);
}
@Transaction
public DatabaseService create(DatabaseService databaseService) throws JsonProcessingException {
// Validate fields

View File

@ -68,11 +68,11 @@ public abstract class EntityRepository<T> {
return getResultList(entities, beforeCursor, afterCursor, total);
}
@Transaction
public final int listCount(String fqnPrefix) {
return dao.listCount(fqnPrefix);
}
// @Transaction
// public final int listCount(String fqnPrefix) {
// return dao.listCount(fqnPrefix);
// }
//
@Transaction
public final T get(String id, Fields fields) throws IOException, ParseException {
return setFields(dao.findEntityById(id), fields);

View File

@ -45,21 +45,6 @@ public class MessagingServiceRepositoryHelper extends EntityRepository<Messaging
this.repo3 = repo3;
}
@Transaction
public List<MessagingService> list(String name) throws IOException {
return JsonUtils.readObjects(repo3.messagingServiceDAO().list(name), MessagingService.class);
}
@Transaction
public MessagingService get(String id) throws IOException {
return repo3.messagingServiceDAO().findEntityById(id);
}
@Transaction
public MessagingService getByName(String name) throws IOException {
return repo3.messagingServiceDAO().findEntityByName(name);
}
@Transaction
public MessagingService create(MessagingService messagingService) throws JsonProcessingException {
// Validate fields

View File

@ -74,16 +74,6 @@ public class MetricsRepositoryHelper extends EntityRepository<Metrics> {
return new PutResponse<>(Status.OK, updated);
}
@Transaction
public List<Metrics> list(Fields fields) throws IOException {
List<String> jsonList = repo3.metricsDAO().list();
List<Metrics> metricsList = new ArrayList<>();
for (String json : jsonList) {
metricsList.add(setFields(JsonUtils.readValue(json, Metrics.class), fields));
}
return metricsList;
}
@Override
public String getFullyQualifiedName(Metrics entity) {
return entity.getFullyQualifiedName();

View File

@ -17,28 +17,4 @@ public interface ModelDAO3 extends EntityDAO<Model>{
@Override
default String getNameColumn() { return "fullyQualifiedName"; }
@Override
@SqlQuery("SELECT count(*) FROM <table>")
int listCount(@Define("table") String table);
@SqlQuery(
"SELECT json FROM (" +
"SELECT fullyQualifiedName, json FROM model_entity WHERE " +
"fullyQualifiedName < :before " + // Pagination by model fullyQualifiedName
"ORDER BY fullyQualifiedName DESC " +
"LIMIT :limit" +
") last_rows_subquery ORDER BY fullyQualifiedName")
List<String> listBefore(@Bind("limit") int limit,
@Bind("before") String before);
@SqlQuery("SELECT json FROM model_entity WHERE " +
"fullyQualifiedName > :after " +
"ORDER BY fullyQualifiedName " +
"LIMIT :limit")
List<String> listAfter(@Bind("limit") int limit,
@Bind("after") String after);
@SqlQuery("SELECT count(*) FROM model_entity")
int listCount();
}

View File

@ -66,48 +66,6 @@ public class ModelRepositoryHelper extends EntityRepository<Model> {
return (model.getName());
}
@Transaction
public ModelList listAfter(Fields fields, int limitParam, String after) throws IOException,
GeneralSecurityException {
// forward scrolling, if after == null then first page is being asked being asked
List<String> jsons =repo3.modelDAO().listAfter(limitParam + 1, after == null ? "" :
CipherText.instance().decrypt(after));
List<Model> models = new ArrayList<>();
for (String json : jsons) {
models.add(setFields(JsonUtils.readValue(json, Model.class), fields));
}
int total =repo3.modelDAO().listCount();
String beforeCursor, afterCursor = null;
beforeCursor = after == null ? null : models.get(0).getFullyQualifiedName();
if (models.size() > limitParam) { // If extra result exists, then next page exists - return after cursor
models.remove(limitParam);
afterCursor = models.get(limitParam - 1).getFullyQualifiedName();
}
return new ModelList(models, beforeCursor, afterCursor, total);
}
@Transaction
public ModelList listBefore(Fields fields, int limitParam, String before)
throws IOException, GeneralSecurityException {
// Reverse scrolling - Get one extra result used for computing before cursor
List<String> jsons =repo3.modelDAO().listBefore(limitParam + 1, CipherText.instance().decrypt(before));
List<Model> models = new ArrayList<>();
for (String json : jsons) {
models.add(setFields(JsonUtils.readValue(json, Model.class), fields));
}
int total =repo3.modelDAO().listCount();
String beforeCursor = null, afterCursor;
if (models.size() > limitParam) { // If extra result exists, then previous page exists - return before cursor
models.remove(0);
beforeCursor = models.get(0).getFullyQualifiedName();
}
afterCursor = models.get(models.size() - 1).getFullyQualifiedName();
return new ModelList(models, beforeCursor, afterCursor, total);
}
@Transaction
public Model create(Model model) throws IOException {
validateRelationships(model);

View File

@ -46,21 +46,6 @@ public class PipelineServiceRepositoryHelper extends EntityRepository<PipelineSe
private final PipelineServiceRepository3 repo3;
@Transaction
public List<PipelineService> list(String name) throws IOException {
return JsonUtils.readObjects(repo3.pipelineServiceDAO().list(name), PipelineService.class);
}
@Transaction
public PipelineService get(String id) throws IOException {
return repo3.pipelineServiceDAO().findEntityById(id);
}
@Transaction
public PipelineService getByName(String name) throws IOException {
return repo3.pipelineServiceDAO().findEntityByName(name);
}
@Transaction
public PipelineService create(PipelineService pipelineService) throws JsonProcessingException {
// Validate fields

View File

@ -17,26 +17,4 @@ public interface TeamDAO3 extends EntityDAO<Team> {
@Override
default String getNameColumn() { return "name"; }
@Override
@SqlQuery("SELECT count(*) FROM <table>")
int listCount(@Define("table") String table);
@SqlQuery("SELECT count(*) FROM team_entity")
int listCount();
@SqlQuery(
"SELECT json FROM (" +
"SELECT name, json FROM team_entity WHERE " +
"name < :before " + // Pagination by team name
"ORDER BY name DESC " + // Pagination ordering by team name
"LIMIT :limit" +
") last_rows_subquery ORDER BY name")
List<String> listBefore(@Bind("limit") int limit, @Bind("before") String before);
@SqlQuery("SELECT json FROM team_entity WHERE " +
"name > :after " + // Pagination by team name
"ORDER BY name " + // Pagination ordering by team name
"LIMIT :limit")
List<String> listAfter(@Bind("limit") int limit, @Bind("after") String after);
}

View File

@ -78,48 +78,6 @@ public class TeamRepositoryHelper extends EntityRepository<Team> {
return team;
}
@Transaction
public TeamList listAfter(Fields fields, int limitParam, String after) throws IOException, GeneralSecurityException {
// Forward scrolling, either because after != null or first page is being asked
List<String> jsons = repo3.teamDAO().listAfter(limitParam + 1, after == null ? "" :
CipherText.instance().decrypt(after));
List<Team> teams = new ArrayList<>();
for (String json : jsons) {
teams.add(setFields(JsonUtils.readValue(json, Team.class), fields));
}
int total = repo3.teamDAO().listCount();
String beforeCursor, afterCursor = null;
beforeCursor = after == null ? null : teams.get(0).getName();
if (teams.size() > limitParam) {
teams.remove(limitParam);
afterCursor = teams.get(limitParam - 1).getName();
}
return new TeamList(teams, beforeCursor, afterCursor, total);
}
@Transaction
public TeamList listBefore(Fields fields, int limitParam, String before) throws IOException, GeneralSecurityException {
// Reverse scrolling
List<String> jsons = repo3.teamDAO().listBefore(limitParam + 1, CipherText.instance().decrypt(before));
List<Team> teams = new ArrayList<>();
for (String json : jsons) {
teams.add(setFields(JsonUtils.readValue(json, Team.class), fields));
}
int total = repo3.teamDAO().listCount();
String beforeCursor = null, afterCursor;
if (teams.size() > limitParam) {
teams.remove(0);
beforeCursor = teams.get(0).getName();
}
afterCursor = teams.get(teams.size() - 1).getName();
return new TeamList(teams, beforeCursor, afterCursor, total);
}
@Transaction
public Team patch(String teamId, String user, JsonPatch patch) throws IOException {
Team original = setFields(repo3.teamDAO().findEntityById(teamId), TEAM_PATCH_FIELDS);

View File

@ -84,11 +84,6 @@ public class UserRepositoryHelper extends EntityRepository<User> {
return new UserList(entities, beforeCursor, afterCursor, total);
}
@Transaction
public User get(String id) throws IOException {
return validateUser(id);
}
@Transaction
public User getByEmail(String email, Fields fields) throws IOException {
User user = EntityUtil.validate(email, repo3.userDAO().findByEmail(email), User.class);

View File

@ -25,7 +25,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.openmetadata.catalog.entity.data.Metrics;
import org.openmetadata.catalog.jdbi3.MetricsRepositoryHelper;
import org.openmetadata.catalog.resources.Collection;
import org.openmetadata.catalog.security.CatalogAuthorizer;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.RestUtil;
@ -47,6 +46,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Date;
@ -63,11 +63,6 @@ public class MetricsResource {
public static final String COLLECTION_PATH = "/v1/metrics/";
private final MetricsRepositoryHelper dao;
private static List<Metrics> addHref(UriInfo uriInfo, List<Metrics> metrics) {
metrics.forEach(m -> addHref(uriInfo, m));
return metrics;
}
private static Metrics addHref(UriInfo uriInfo, Metrics metrics) {
metrics.setHref(RestUtil.getHref(uriInfo, COLLECTION_PATH, metrics.getId()));
return metrics;
@ -97,12 +92,15 @@ public class MetricsResource {
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = MetricsList.class)))
})
public MetricsList list(@Context UriInfo uriInfo,
public ResultList<Metrics> list(@Context UriInfo uriInfo,
@Parameter(description = "Fields requested in the returned resource",
schema = @Schema(type = "string", example = FIELDS))
@QueryParam("fields") String fieldsParam) throws IOException {
@QueryParam("fields") String fieldsParam) throws IOException, GeneralSecurityException,
ParseException {
Fields fields = new Fields(FIELD_LIST, fieldsParam);
return new MetricsList(addHref(uriInfo, dao.list(fields)));
ResultList<Metrics> metricsList = dao.listAfter(fields, null, 10000, null);
metricsList.getData().forEach(m -> addHref(uriInfo, m));
return metricsList;
}
@GET

View File

@ -131,7 +131,7 @@ public class ModelResource {
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ModelList.class)))
})
public ModelList list(@Context UriInfo uriInfo,
public ResultList<Model> list(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Fields requested in the returned resource",
schema = @Schema(type = "string", example = FIELDS))
@ -148,15 +148,15 @@ public class ModelResource {
@Parameter(description = "Returns list of models after this cursor",
schema = @Schema(type = "string"))
@QueryParam("after") String after
) throws IOException, GeneralSecurityException {
) throws IOException, GeneralSecurityException, ParseException {
RestUtil.validateCursors(before, after);
Fields fields = new Fields(FIELD_LIST, fieldsParam);
ModelList models;
ResultList<Model> models;
if (before != null) { // Reverse paging
models = dao.listBefore(fields, limitParam, before); // Ask for one extra entry
models = dao.listBefore(fields, null, limitParam, before); // Ask for one extra entry
} else { // Forward paging or first page
models = dao.listAfter(fields, limitParam, after);
models = dao.listAfter(fields, null, limitParam, after);
}
addHref(uriInfo, models.getData());
return models;

View File

@ -28,7 +28,6 @@ import org.openmetadata.catalog.api.services.CreateDashboardService;
import org.openmetadata.catalog.api.services.UpdateDashboardService;
import org.openmetadata.catalog.entity.services.DashboardService;
import org.openmetadata.catalog.jdbi3.DashboardServiceRepositoryHelper;
import org.openmetadata.catalog.resources.Collection;
import org.openmetadata.catalog.security.CatalogAuthorizer;
import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.EntityReference;
@ -51,6 +50,8 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@ -101,8 +102,10 @@ public class DashboardServiceResource {
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = DashboardServiceList.class)))
})
public DashboardServiceList list(@Context UriInfo uriInfo, @QueryParam("name") String name) throws IOException {
return new DashboardServiceList(addHref(uriInfo, dao.list(name)));
public ResultList<DashboardService> list(@Context UriInfo uriInfo, @QueryParam("name") String name) throws IOException, GeneralSecurityException, ParseException {
ResultList<DashboardService> list = dao.listAfter(null, null, 10000, null);
list.getData().forEach(d -> addHref(uriInfo, d));
return list;
}
@GET
@ -117,8 +120,8 @@ public class DashboardServiceResource {
})
public DashboardService get(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("id") String id) throws IOException {
return addHref(uriInfo, dao.get(id));
@PathParam("id") String id) throws IOException, ParseException {
return addHref(uriInfo, dao.get(id, null));
}
@GET
@ -133,8 +136,8 @@ public class DashboardServiceResource {
})
public DashboardService getByName(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("name") String name) throws IOException {
return addHref(uriInfo, dao.getByName(name));
@PathParam("name") String name) throws IOException, ParseException {
return addHref(uriInfo, dao.getByName(name, null));
}
@POST

View File

@ -51,6 +51,8 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@ -100,8 +102,10 @@ public class DatabaseServiceResource {
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = DatabaseServiceList.class)))
})
public DatabaseServiceList list(@Context UriInfo uriInfo, @QueryParam("name") String name) throws IOException {
return new DatabaseServiceList(addHref(uriInfo, dao.list(name)));
public ResultList<DatabaseService> list(@Context UriInfo uriInfo) throws IOException, GeneralSecurityException, ParseException {
ResultList<DatabaseService> list = dao.listAfter(null, null, 10000, null);
list.getData().forEach(d -> addHref(uriInfo, d));
return list;
}
@GET
@ -116,8 +120,8 @@ public class DatabaseServiceResource {
})
public DatabaseService get(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("id") String id) throws IOException {
return addHref(uriInfo, dao.get(id));
@PathParam("id") String id) throws IOException, ParseException {
return addHref(uriInfo, dao.get(id, null));
}
@GET
@ -132,8 +136,8 @@ public class DatabaseServiceResource {
})
public DatabaseService getByName(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("name") String name) throws IOException {
return addHref(uriInfo, dao.getByName(name));
@PathParam("name") String name) throws IOException, ParseException {
return addHref(uriInfo, dao.getByName(name, null));
}
@POST

View File

@ -28,7 +28,6 @@ import org.openmetadata.catalog.api.services.CreateMessagingService;
import org.openmetadata.catalog.api.services.UpdateMessagingService;
import org.openmetadata.catalog.entity.services.MessagingService;
import org.openmetadata.catalog.jdbi3.MessagingServiceRepositoryHelper;
import org.openmetadata.catalog.resources.Collection;
import org.openmetadata.catalog.security.CatalogAuthorizer;
import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.EntityReference;
@ -51,6 +50,8 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@ -100,8 +101,12 @@ public class MessagingServiceResource {
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = MessagingServiceList.class)))
})
public MessagingServiceList list(@Context UriInfo uriInfo, @QueryParam("name") String name) throws IOException {
return new MessagingServiceList(addHref(uriInfo, dao.list(name)));
public ResultList<MessagingService> list(@Context UriInfo uriInfo,
@QueryParam("name") String name) throws IOException,
GeneralSecurityException, ParseException {
ResultList<MessagingService> list = dao.listAfter(null, null, 10000, null);
list.getData().forEach(m -> addHref(uriInfo, m));
return list;
}
@GET
@ -116,8 +121,8 @@ public class MessagingServiceResource {
})
public MessagingService get(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("id") String id) throws IOException {
return addHref(uriInfo, dao.get(id));
@PathParam("id") String id) throws IOException, ParseException {
return addHref(uriInfo, dao.get(id, null));
}
@GET
@ -132,8 +137,8 @@ public class MessagingServiceResource {
})
public MessagingService getByName(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("name") String name) throws IOException {
return addHref(uriInfo, dao.getByName(name));
@PathParam("name") String name) throws IOException, ParseException {
return addHref(uriInfo, dao.getByName(name, null));
}
@POST

View File

@ -28,7 +28,6 @@ import org.openmetadata.catalog.api.services.CreatePipelineService;
import org.openmetadata.catalog.api.services.UpdatePipelineService;
import org.openmetadata.catalog.entity.services.PipelineService;
import org.openmetadata.catalog.jdbi3.PipelineServiceRepositoryHelper;
import org.openmetadata.catalog.resources.Collection;
import org.openmetadata.catalog.security.CatalogAuthorizer;
import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.EntityReference;
@ -51,6 +50,8 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@ -101,8 +102,11 @@ public class PipelineServiceResource {
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = PipelineServiceList.class)))
})
public PipelineServiceList list(@Context UriInfo uriInfo, @QueryParam("name") String name) throws IOException {
return new PipelineServiceList(addHref(uriInfo, dao.list(name)));
public ResultList<PipelineService> list(@Context UriInfo uriInfo, @QueryParam("name") String name) throws IOException,
GeneralSecurityException, ParseException {
ResultList<PipelineService> list = dao.listAfter(null, null, 10000, null);
list.getData().forEach(p -> addHref(uriInfo, p));
return list;
}
@GET
@ -117,8 +121,8 @@ public class PipelineServiceResource {
})
public PipelineService get(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("id") String id) throws IOException {
return addHref(uriInfo, dao.get(id));
@PathParam("id") String id) throws IOException, ParseException {
return addHref(uriInfo, dao.get(id, null));
}
@GET
@ -133,8 +137,8 @@ public class PipelineServiceResource {
})
public PipelineService getByName(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("name") String name) throws IOException {
return addHref(uriInfo, dao.getByName(name));
@PathParam("name") String name) throws IOException, ParseException {
return addHref(uriInfo, dao.getByName(name, null));
}
@POST

View File

@ -122,7 +122,7 @@ public class TeamResource {
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = TeamList.class)))
})
public TeamList list(@Context UriInfo uriInfo,
public ResultList<Team> list(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Fields requested in the returned resource",
schema = @Schema(type = "string", example = FIELDS))
@ -138,15 +138,15 @@ public class TeamResource {
@QueryParam("before") String before,
@Parameter(description = "Returns list of tables after this cursor",
schema = @Schema(type = "string"))
@QueryParam("after") String after) throws IOException, GeneralSecurityException {
@QueryParam("after") String after) throws IOException, GeneralSecurityException, ParseException {
RestUtil.validateCursors(before, after);
EntityUtil.Fields fields = new EntityUtil.Fields(FIELD_LIST, fieldsParam);
TeamList teams;
ResultList<Team> teams;
if (before != null) { // Reverse paging
teams = dao.listBefore(fields, limitParam, before); // Ask for one extra entry
teams = dao.listBefore(fields, null, limitParam, before); // Ask for one extra entry
} else { // Forward paging or first page
teams = dao.listAfter(fields, limitParam, after);
teams = dao.listAfter(fields, null, limitParam, after);
}
teams.getData().forEach(team -> addHref(uriInfo, team));
return teams;

View File

@ -284,8 +284,8 @@ public class UserResource {
"{op:remove, path:/a}," +
"{op:add, path: /b, value: val}" +
"]")}))
JsonPatch patch) throws IOException {
User user = dao.get(id);
JsonPatch patch) throws IOException, ParseException {
User user = dao.get(id, new Fields(FIELD_LIST, null));
SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext,
EntityUtil.getEntityReference(user));
return addHref(uriInfo, dao.patch(id, securityContext.getUserPrincipal().getName(), patch));