From 0b96a95399cac02fee614523ae5b552c99c1e254 Mon Sep 17 00:00:00 2001 From: pujavs <43700552+pujavs@users.noreply.github.com> Date: Fri, 5 Aug 2022 01:53:53 +0530 Subject: [PATCH] feat(jans-config-api): agama patch endpoint (#2028) * bug(jans-config-api): fixed swagger format issue * fix(jans-config-api): fixed due to couchbase clustter change * feat(jans-config-api): new endpoint to get UmaResource based on associatedClient * fix(jans-config-api): swagger spec fix for client attributes * fix(jans-config-api): reverted the local test properties * test(jans-config-api): commented test case * feat(jans-config-api): scim config endpoint enhancment * feat(jans-config-api): swagger and DTO change for new fields for scim config endpoint * feat(jans-config-api): swagger and DTO change for new fields for scim config endpoint * fix(jans-config-api): rectified endpoint url in swagger spec for uma resource * feat(jans-config-api): agama endpoint fixes * fix(jans-config-api): agama endpoint enhancements * fix(jans-config-api): fixed swagger spec for Uma Resource delete * fix(jans-config-api): agama endpoint enhancements * fix(jans-config-api): agama endpoint enhancements * fix(jans-config-api): agama endpoint enhancements * fix(jans-config-api): agama endpoint enhancements * fix(jans-config-api): agama endpoint enhancements * feat(jans-config-api): agama patch endpoint * feat(jans-config-api): agama patch endpoint * feat(jans-config-api): agama patch endpoint --- .../rest/resource/auth/AgamaResource.java | 177 ++++++++++-------- .../configapi/core/rest/BaseResource.java | 36 ++-- .../io/jans/configapi/core/util/DataUtil.java | 40 ++-- .../io/jans/configapi/core/util/Jackson.java | 5 + 4 files changed, 147 insertions(+), 111 deletions(-) diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AgamaResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AgamaResource.java index d4ce0ee3e79..6bad7eb3cf0 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AgamaResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AgamaResource.java @@ -40,15 +40,13 @@ import org.slf4j.Logger; import com.github.fge.jsonpatch.JsonPatchException; +import com.github.fge.jsonpatch.JsonPatch; @Path(ApiConstants.AGAMA) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public class AgamaResource extends ConfigBaseResource { - @Inject - Logger log; - @Inject AgamaFlowService agamaFlowService; @@ -58,8 +56,8 @@ public Response getFlows(@DefaultValue("") @QueryParam(value = ApiConstants.PATT @DefaultValue(DEFAULT_LIST_SIZE) @QueryParam(value = ApiConstants.LIMIT) int limit, @DefaultValue("false") @QueryParam(value = ApiConstants.INCLUDE_SOURCE) boolean includeSource) { - if (log.isDebugEnabled()) { - log.debug("Search Agama Flow with pattern:{}, sizeLimit:{}, includeSource:{}", escapeLog(pattern), + if (logger.isDebugEnabled()) { + logger.debug("Search Agama Flow with pattern:{}, sizeLimit:{}, includeSource:{}", escapeLog(pattern), escapeLog(limit), escapeLog(includeSource)); } @@ -80,12 +78,13 @@ public Response getFlows(@DefaultValue("") @QueryParam(value = ApiConstants.PATT @Path(ApiConstants.QNAME_PATH) public Response getFlowByName(@PathParam(ApiConstants.QNAME) @NotNull String flowName, @DefaultValue("false") @QueryParam(value = ApiConstants.INCLUDE_SOURCE) boolean includeSource) { - if (log.isDebugEnabled()) { - log.debug("Search Agama with flowName:{}, includeSource:{}", escapeLog(flowName), escapeLog(includeSource)); + if (logger.isDebugEnabled()) { + logger.debug("Search Agama with flowName:{}, includeSource:{}", escapeLog(flowName), + escapeLog(includeSource)); } String decodedFlowName = getURLDecodedValue(flowName); - log.trace(" Agama Decoded flow name decodedFlowName:{}", decodedFlowName); + logger.trace(" Agama Decoded flow name decodedFlowName:{}", decodedFlowName); Flow flow = findFlow(decodedFlowName, true, includeSource); return Response.ok(flow).build(); @@ -95,22 +94,19 @@ public Response getFlowByName(@PathParam(ApiConstants.QNAME) @NotNull String flo @ProtectedApi(scopes = { ApiAccessConstants.AGAMA_WRITE_ACCESS }) public Response createFlow(@Valid Flow flow) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - log.debug(" Flow to be added flow:{}, flow.getQName():{}, flow.getSource():{} ", flow, flow.getQname(), + logger.debug(" Flow to be added flow:{}, flow.getQName():{}, flow.getSource():{} ", flow, flow.getQname(), flow.getSource()); // check if flow with same name already exists Flow existingFlow = findFlow(flow.getQname(), false, false); - log.debug(" existingFlow:{}", existingFlow); + logger.debug(" existingFlow:{}", existingFlow); if (existingFlow != null) { thorwBadRequestException("Flow identified by name '" + flow.getQname() + "' already exist!"); } // validate flow data + updateFlowDetails(flow, null); validateAgamaFlowData(flow, true); - flow.setRevision(-1); - FlowMetadata flowMetadata = new FlowMetadata(); - flowMetadata.setTimestamp(System.currentTimeMillis()); - flow.setMetadata(flowMetadata); agamaFlowService.addAgamaFlow(flow); flow = findFlow(flow.getQname(), true, false); @@ -123,14 +119,14 @@ public Response createFlow(@Valid Flow flow) @ProtectedApi(scopes = { ApiAccessConstants.AGAMA_WRITE_ACCESS }) public Response createFlowFromFile(@PathParam(ApiConstants.QNAME) @NotNull String flowName, @Valid String source) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - log.debug(" Flow to be created flowName:{}, source:{}", flowName, source); + logger.debug(" Flow to be created flowName:{}, source:{}", flowName, source); String decodedFlowName = getURLDecodedValue(flowName); - log.trace(" Agama Decoded flow name for create is:{}", decodedFlowName); + logger.trace(" Agama Decoded flow name for create is:{}", decodedFlowName); // check if flow with same name already exists Flow existingFlow = findFlow(decodedFlowName, false, false); - log.debug(" existing-flow:{}", existingFlow); + logger.debug(" existing-flow:{}", existingFlow); if (existingFlow != null) { thorwBadRequestException("Flow identified by name '" + decodedFlowName + "' already exist!"); } @@ -139,10 +135,7 @@ public Response createFlowFromFile(@PathParam(ApiConstants.QNAME) @NotNull Strin flow.setQname(decodedFlowName); flow.setSource(source); flow.setEnabled(true); - flow.setRevision(-1); - FlowMetadata flowMetadata = new FlowMetadata(); - flowMetadata.setTimestamp(System.currentTimeMillis()); - flow.setMetadata(flowMetadata); + updateFlowDetails(flow, null); // validate flow data validateAgamaFlowData(flow, true); @@ -157,25 +150,23 @@ public Response createFlowFromFile(@PathParam(ApiConstants.QNAME) @NotNull Strin @ProtectedApi(scopes = { ApiAccessConstants.AGAMA_WRITE_ACCESS }) public Response updateFlow(@PathParam(ApiConstants.QNAME) @NotNull String flowName, @Valid Flow flow) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - log.debug(" Flow to update flowName:{}, flow:{}, flow.getQName():{}, flow.getSource():{} ", flowName, flow, + logger.debug(" Flow to update flowName:{}, flow:{}, flow.getQName():{}, flow.getSource():{} ", flowName, flow, flow.getQname(), flow.getSource()); String decodedFlowName = getURLDecodedValue(flowName); - log.trace(" Agama Decoded flow name for update is:{}", decodedFlowName); + logger.trace(" Agama Decoded flow name for update is:{}", decodedFlowName); // check if flow exists Flow existingFlow = findFlow(decodedFlowName, true, false); // set flow data flow.setQname(decodedFlowName); - log.trace("Flow revision check - flow.getRevision():{}, existingFlow.getRevision():{}", flow.getRevision(), - existingFlow.getRevision()); - getRevision(flow, existingFlow); - log.debug("Flow revision after update - flow.getRevision():{}", flow.getRevision()); + updateFlowDetails(flow, existingFlow); + logger.debug("Flow revision after update - flow.getRevision():{}", flow.getRevision()); // validate flow data validateAgamaFlowData(flow, false); - log.debug("Updating flow after validation"); + logger.debug("Updating flow after validation"); agamaFlowService.updateFlow(flow); flow = findFlow(decodedFlowName, true, false); @@ -188,24 +179,24 @@ public Response updateFlow(@PathParam(ApiConstants.QNAME) @NotNull String flowNa @ProtectedApi(scopes = { ApiAccessConstants.AGAMA_WRITE_ACCESS }) public Response updateFlowFromFile(@PathParam(ApiConstants.QNAME) @NotNull String flowName, @Valid String source) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - log.debug(" Flow to be updated flowName:{}, source:{}", flowName, source); + logger.debug(" Flow to be updated flowName:{}, source:{}", flowName, source); String decodedFlowName = getURLDecodedValue(flowName); - log.trace(" Agama flow name for update is:{}", decodedFlowName); + logger.trace(" Agama flow name for update is:{}", decodedFlowName); - // check if flow with same name already exists - Flow existingFlow = findFlow(decodedFlowName, false, false); - log.debug(" Agama existingFlow:{}", existingFlow); + // check if flow with same name exists + Flow existingFlow = findFlow(decodedFlowName, true, false); + logger.debug(" Agama existingFlow:{}", existingFlow); // Update source and revision if (existingFlow != null) { existingFlow.setSource(source); - getRevision(existingFlow, existingFlow); + updateFlowDetails(existingFlow, existingFlow); // validate flow data validateAgamaFlowData(existingFlow, false); - log.debug("Update flow after validation"); + logger.debug("Update flow after validation"); agamaFlowService.updateFlow(existingFlow); existingFlow = findFlow(existingFlow.getQname(), true, false); @@ -217,26 +208,28 @@ public Response updateFlowFromFile(@PathParam(ApiConstants.QNAME) @NotNull Strin @Consumes(MediaType.APPLICATION_JSON_PATCH_JSON) @Path(ApiConstants.QNAME_PATH) @ProtectedApi(scopes = { ApiAccessConstants.AGAMA_WRITE_ACCESS }) - public Response patchFlow(@PathParam(ApiConstants.QNAME) @NotNull String flowName, @NotNull String pathString) + public Response patchFlow(@PathParam(ApiConstants.QNAME) @NotNull String flowName, @NotNull JsonPatch jsonPatch) throws JsonPatchException, IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (logger.isDebugEnabled()) { - logger.debug("Flow details to be patched - flowName:{}, pathString:{}", escapeLog(flowName), - escapeLog(pathString)); + logger.debug("Flow details to be patched - flowName:{}, jsonPatch:{}", escapeLog(flowName), + escapeLog(jsonPatch)); } + String decodedFlowName = getURLDecodedValue(flowName); - log.trace(" Flow name for update is:{}", decodedFlowName); + logger.debug(" Flow to be patched is name:{}", decodedFlowName); // check if flow exists Flow existingFlow = findFlow(decodedFlowName, false, true); - log.debug(" existingFlow:{}", existingFlow); + logger.debug(" Flow to be patched:{}", existingFlow); - existingFlow = Jackson.applyPatch(pathString, existingFlow); - getRevision(existingFlow, existingFlow); + existingFlow = Jackson.applyJsonPatch(jsonPatch, existingFlow); + logger.debug(" After patch flow:{}", existingFlow); + updateFlowDetails(existingFlow, existingFlow); // validate flow data validateAgamaFlowData(existingFlow, false); - log.debug("Updating flow after validation"); + logger.debug("Updating flow after validation"); agamaFlowService.updateFlow(existingFlow); return Response.ok(existingFlow).build(); } @@ -245,9 +238,9 @@ public Response patchFlow(@PathParam(ApiConstants.QNAME) @NotNull String flowNam @Path(ApiConstants.QNAME_PATH) @ProtectedApi(scopes = { ApiAccessConstants.AGAMA_DELETE_ACCESS }) public Response deleteAttribute(@PathParam(ApiConstants.QNAME) @NotNull String flowName) { - log.debug(" Flow to delete - flowName:{}", flowName); + logger.debug(" Flow to delete - flowName:{}", flowName); String decodedFlowName = getURLDecodedValue(flowName); - log.trace(" Agama Decoded flow name is:{}", decodedFlowName); + logger.trace(" Agama Decoded flow name is:{}", decodedFlowName); // check if flow exists Flow flow = findFlow(decodedFlowName, true, false); @@ -262,15 +255,17 @@ private Flow findFlow(String flowName, boolean throwError, boolean includeSource flow = agamaFlowService.getFlowByName(flowName); // filter values - List flows = Arrays.asList(flow); - getAgamaFlowDetails(flows, includeSource); - if (flows != null && !flows.isEmpty()) { - flow = flows.get(0); + if (flow != null) { + List flows = Arrays.asList(flow); + getAgamaFlowDetails(flows, includeSource); + if (flows != null && !flows.isEmpty()) { + flow = flows.get(0); + } } } catch (EntryPersistenceException e) { - log.error("No flow found with the name:{} ", flowName); + logger.error("No flow found with the name:{} ", flowName); if (throwError) { - throw new NotFoundException(getNotFoundError("Flow - " + flowName + "!!!")); + throw new NotFoundException(getNotFoundError("Flow - '" + flowName + "'")); } } return flow; @@ -278,15 +273,15 @@ private Flow findFlow(String flowName, boolean throwError, boolean includeSource private void validateAgamaFlowData(Flow flow, boolean checkNonMandatoryFields) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - log.debug(" Validate Agama Flow data - flow:{}, checkNonMandatoryFields:{}", flow, checkNonMandatoryFields); + logger.debug(" Validate Agama Flow data - flow:{}, checkNonMandatoryFields:{}", flow, checkNonMandatoryFields); if (flow == null) { return; } - log.debug("Agama Flow to be added flow:{}, flow.getQname():{}, flow.getSource():{} ", flow, flow.getQname(), + logger.debug("Agama Flow to be added flow:{}, flow.getQname():{}, flow.getSource():{} ", flow, flow.getQname(), flow.getSource()); String validateMsg = agamaFlowService.validateFlowFields(flow, checkNonMandatoryFields); - log.debug("Agama Flow to be validation msg:{} ", validateMsg); + logger.debug("Agama Flow to be validation msg:{} ", validateMsg); if (StringUtils.isNotBlank(validateMsg)) { thorwBadRequestException(validateMsg); } @@ -296,7 +291,7 @@ private void validateAgamaFlowData(Flow flow, boolean checkNonMandatoryFields) } private void validateSyntax(Flow flow) { - log.debug("Validate Flow Source Syntax - flow:{}", flow); + logger.debug("Validate Flow Source Syntax - flow:{}", flow); if (flow == null) { return; } @@ -304,63 +299,97 @@ private void validateSyntax(Flow flow) { try { Transpiler.runSyntaxCheck(flow.getQname(), flow.getSource()); } catch (SyntaxException se) { - log.error("Transpiler syntax check error", se); + logger.error("Transpiler syntax check error", se); try { - log.debug("Throwing BadRequestException 400 :{} ", Jackson.asPrettyJson(se)); - thorwBadRequestException(Jackson.asJson(se)); + logger.debug("Throwing BadRequestException 400 :{} ", Jackson.asPrettyJson(se)); + thorwBadRequestException(se); } catch (IOException io) { - log.error("Agama Flow Transpiler syntax error parsing error", io); + logger.error("Agama Flow Transpiler syntax error parsing error", io); thorwBadRequestException("Transpiler syntax check error" + se); } } catch (TranspilerException te) { - log.error("Agama Flow transpiler exception", te); - thorwBadRequestException(te.toString()); + logger.error("Agama Flow transpiler exception", te); + thorwBadRequestException(te); } } private String getURLDecodedValue(String pathParam) { - log.debug(" Decode pathParam():{} ", pathParam); + logger.debug(" Decode pathParam():{} ", pathParam); try { return URLDecoder.decode(pathParam, UTF_8.name()); } catch (UnsupportedEncodingException uee) { - log.error("Agama Flow error while URL decoding pathParam:{}, is:{}", pathParam, uee); + logger.error("Agama Flow error while URL decoding pathParam:{}, is:{}", pathParam, uee); } return pathParam; } - private Flow getRevision(Flow flow, Flow existingFlow) { - log.debug("Flow revision check - flow:{}, existingFlow:{}", flow, existingFlow); + private Flow updateFlowDetails(Flow flow, Flow existingFlow) { + logger.debug("Update Flow details - flow:{}, existingFlow:{}", flow, existingFlow); + + updateRevision(flow, existingFlow); + updateMetadata(flow); + return flow; + } + + private Flow updateRevision(Flow flow, Flow existingFlow) { + logger.debug("Flow revision check - flow:{}, existingFlow:{}", flow, existingFlow); + + if (flow == null) { + return flow; + } - if (flow == null || existingFlow == null) { + if (existingFlow == null) { + flow.setRevision(-1); return flow; } - log.debug("Flow revision check - flow.getRevision():{}, existingFlow.getRevision():{}", flow.getRevision(), - existingFlow.getRevision()); + logger.trace("Flow revision before update - flow.getRevision():{}, existingFlow.getRevision():{}", + flow.getRevision(), existingFlow.getRevision()); - if (flow.getSource() != null && flow.getRevision() == 0) { - if (existingFlow.getRevision() == 0 || existingFlow.getRevision() == -1) { + if (flow.getSource() != null && (flow.getRevision() <= 0 || flow.getRevision() == existingFlow.getRevision())) { + if (existingFlow.getRevision() <= 0) { flow.setRevision(1); } else { flow.setRevision(existingFlow.getRevision() + 1); } } - log.debug("Final flow revision to be updated to - flow.getRevision():{}", flow.getRevision()); + logger.trace("Flow revision after update - flow.getRevision():{}", flow.getRevision()); + return flow; + } + + private Flow updateMetadata(Flow flow) { + logger.debug("Update Flow Metadata - flow:{}", flow); + + if (flow == null) { + return flow; + } + + FlowMetadata flowMetadata = flow.getMetadata(); + if (flowMetadata == null) { + flowMetadata = new FlowMetadata(); + } + + logger.trace("Flow Metadata Timestamp before update - flowMetadata.getTimestamp():{}", + flowMetadata.getTimestamp()); + flowMetadata.setTimestamp(System.currentTimeMillis()); + flow.setMetadata(flowMetadata); + + logger.trace("Flow Metadata Timestamp after update - flowMetadata.getTimestamp():{}", + flowMetadata.getTimestamp()); return flow; } private List getAgamaFlowDetails(List flows, boolean includeSource) { - log.debug("Flow data filter - flows:{}, includeSource:{}", flows, includeSource); + logger.debug("Flow data filter - flows:{}, includeSource:{}", flows, includeSource); if (flows == null || flows.isEmpty()) { return flows; } for (Flow flow : flows) { - flow.setTranspiled(null); flow.setTransHash(null); - + if (!includeSource) { flow.setSource(null); } diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/rest/BaseResource.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/rest/BaseResource.java index 5fb4bf0dfb3..af3e1aed3c0 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/rest/BaseResource.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/rest/BaseResource.java @@ -11,23 +11,20 @@ import io.jans.configapi.core.model.SearchRequest; import io.jans.orm.model.SortOrder; -import jakarta.inject.Inject; import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.InternalServerErrorException; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.core.Response; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; +import java.util.Map.Entry; import java.util.stream.Collectors; -import java.util.Optional; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + public class BaseResource { private static Logger log = LoggerFactory.getLogger(BaseResource.class); @@ -35,7 +32,6 @@ public class BaseResource { public static final String MISSING_ATTRIBUTE_CODE = "OCA001"; public static final String MISSING_ATTRIBUTE_MESSAGE = "A required attribute is missing."; - public static void checkResourceNotNull(T resource, String objectName) { if (resource == null) { throw new NotFoundException(getNotFoundError(objectName)); @@ -53,20 +49,18 @@ public static void checkNotNull(String[] attributes, String attributeName) { throw new BadRequestException(getMissingAttributeError(attributeName)); } } - - public static void checkNotNull(HashMap attributeMap) { + + public static void checkNotNull(Map attributeMap) { if (attributeMap.isEmpty()) { return; } - - Map map = (Map) attributeMap.entrySet() - .stream() - .filter(k -> (k.getValue() == null || StringUtils.isNotEmpty(k.getValue())) ) - .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue())); - - + + Map map = attributeMap.entrySet().stream() + .filter(k -> (k.getValue() == null || StringUtils.isNotEmpty(k.getValue()))) + .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); + log.debug(" map:{}", map); - if(!map.isEmpty()) { + if (!map.isEmpty()) { throw new BadRequestException(getMissingAttributeError(map.keySet().toString())); } } @@ -92,7 +86,11 @@ public static void checkNotEmpty(String attribute, String attributeName) { public static void thorwBadRequestException(String msg) { throw new BadRequestException(getBadRequestException(msg)); } - + + public static void thorwBadRequestException(Object obj) { + throw new BadRequestException(getBadRequestException(obj)); + } + public static void thorwInternalServerException(String msg) { throw new InternalServerErrorException(getInternalServerException(msg)); } @@ -126,6 +124,10 @@ protected static Response getBadRequestException(String msg) { return Response.status(Response.Status.BAD_REQUEST).entity(error).build(); } + protected static Response getBadRequestException(Object obj) { + return Response.status(Response.Status.BAD_REQUEST).entity(obj).build(); + } + protected static Response getInternalServerException(String msg) { ApiError error = new ApiError.ErrorBuilder() .withCode(String.valueOf(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())).withMessage(msg) diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/DataUtil.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/DataUtil.java index 16b6408fb85..c58ea277495 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/DataUtil.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/DataUtil.java @@ -32,22 +32,22 @@ public class DataUtil { private static final Logger logger = LoggerFactory.getLogger(DataUtil.class); public static Class getPropertType(String className, String name) throws MappingException { - logger.error("className:{} , name:{} ", className, name); + logger.debug("className:{} , name:{} ", className, name); return ReflectHelper.reflectedPropertyClass(className, name); } public static Getter getGetterMethod(Class clazz, String name) throws MappingException { - logger.error("Get Getter fromclazz:{} , name:{} ", clazz, name); + logger.debug("Get Getter fromclazz:{} , name:{} ", clazz, name); return ReflectHelper.getGetter(clazz, name); } public static Setter getSetterMethod(Class clazz, String name) throws MappingException { - logger.error("Get Setter from clazz:{} for name:{} ", clazz, name); + logger.debug("Get Setter from clazz:{} for name:{} ", clazz, name); return ReflectHelper.getSetter(clazz, name); } public static Object getValue(Object object, String property) throws MappingException { - logger.error("Get value from object:{} for property:{} ", object, property); + logger.debug("Get value from object:{} for property:{} ", object, property); return ReflectHelper.getValue(object, property); } @@ -61,10 +61,10 @@ public static Method getSetter(String fieldName, Class clazz) throws Introspe public static Object invokeMethod(Class clazz, String methodName, Class... parameterTypes) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - logger.error("Invoke clazz:{} on methodName:{} with name:{} ", clazz, methodName, parameterTypes); + logger.debug("Invoke clazz:{} on methodName:{} with name:{} ", clazz, methodName, parameterTypes); Method m = clazz.getDeclaredMethod(methodName, parameterTypes); Object obj = m.invoke(null, parameterTypes); - logger.error("methodName:{} returned obj:{} ", methodName, obj); + logger.debug("methodName:{} returned obj:{} ", methodName, obj); return obj; } @@ -105,41 +105,41 @@ public static void invokeReflectionSetter(Object obj, String propertyName, Objec } public static boolean containsField(List allFields, String attribute) { - logger.error("allFields:{}, attribute:{}, allFields.contains(attribute):{} ", allFields, attribute, + logger.debug("allFields:{}, attribute:{}, allFields.contains(attribute):{} ", allFields, attribute, allFields.stream().anyMatch(f -> f.getName().equals(attribute))); return allFields.stream().anyMatch(f -> f.getName().equals(attribute)); } public boolean isStringField(Map objectPropertyMap, String attribute) { - logger.error("Check if field is string objectPropertyMap:{}, attribute:{} ", objectPropertyMap, attribute); + logger.debug("Check if field is string objectPropertyMap:{}, attribute:{} ", objectPropertyMap, attribute); if (objectPropertyMap == null || StringUtils.isBlank(attribute)) { return false; } - logger.error("attribute:{} , datatype:{}", attribute, objectPropertyMap.get(attribute)); + logger.debug("attribute:{} , datatype:{}", attribute, objectPropertyMap.get(attribute)); return ("java.lang.String".equalsIgnoreCase(objectPropertyMap.get(attribute))); } public static List getAllFields(Class type) { List allFields = new ArrayList<>(); getAllFields(allFields, type); - logger.error("Fields:{} of type:{} ", allFields, type); + logger.debug("Fields:{} of type:{} ", allFields, type); return allFields; } public static List getAllFields(List fields, Class type) { - logger.error("Getting fields type:{} - fields:{} ", type, fields); + logger.debug("Getting fields type:{} - fields:{} ", type, fields); fields.addAll(Arrays.asList(type.getDeclaredFields())); if (type.getSuperclass() != null) { getAllFields(fields, type.getSuperclass()); } - logger.error("Final fields:{} of type:{} ", fields, type); + logger.debug("Final fields:{} of type:{} ", fields, type); return fields; } public static Map getFieldTypeMap(Class clazz) { - logger.error("clazz:{} ", clazz); + logger.debug("clazz:{} ", clazz); Map propertyTypeMap = new HashMap<>(); if (clazz == null) { @@ -147,17 +147,17 @@ public static Map getFieldTypeMap(Class clazz) { } List fields = getAllFields(clazz); - logger.error("AllFields:{} ", fields); + logger.debug("AllFields:{} ", fields); for (Field field : fields) { - logger.error( + logger.debug( "field:{} , field.getAnnotatedType():{}, field.getAnnotations():{} , field.getType().getAnnotations():{}, field.getType().getCanonicalName():{} , field.getType().getClass():{} , field.getType().getClasses():{} , field.getType().getComponentType():{}", field, field.getAnnotatedType(), field.getAnnotations(), field.getType().getAnnotations(), field.getType().getCanonicalName(), field.getType().getClass(), field.getType().getClasses(), field.getType().getComponentType()); propertyTypeMap.put(field.getName(), field.getType().getSimpleName()); } - logger.error("Final propertyTypeMap{} ", propertyTypeMap); + logger.debug("Final propertyTypeMap{} ", propertyTypeMap); return propertyTypeMap; } @@ -166,23 +166,23 @@ public static Object invokeGetterMethod(Object obj, String variableName) { } public static boolean isKeyPresentInMap(String key, Map map) { - logger.error("Check key:{} is present in map:{}", key, map); + logger.debug("Check key:{} is present in map:{}", key, map); if (StringHelper.isEmpty(key) || map == null || map.isEmpty()) { return false; } - logger.error(" key:{} present in map:{} ?:{}", key, map, map.keySet().contains(key)); + logger.debug(" key:{} present in map:{} ?:{}", key, map, map.keySet().contains(key)); return map.keySet().contains(key); } public static boolean isAttributeInExclusion(String className, String attribute, Map> exclusionMap) { - logger.error("Check if object:{} attribute:{} is in exclusionMap:{}", className, attribute, exclusionMap); + logger.debug("Check if object:{} attribute:{} is in exclusionMap:{}", className, attribute, exclusionMap); if (StringHelper.isEmpty(className) || StringHelper.isEmpty(attribute) || exclusionMap == null || exclusionMap.isEmpty()) { return false; } - logger.error("Map contains key exclusionMap.keySet().contains(className):{}", + logger.debug("Map contains key exclusionMap.keySet().contains(className):{}", exclusionMap.keySet().contains(className)); if (exclusionMap.keySet().contains(className)) { diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/Jackson.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/Jackson.java index 89fbc36e898..a454897181f 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/Jackson.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/Jackson.java @@ -55,6 +55,11 @@ public static T applyPatch(String patchAsString, T obj) throws JsonPatchExce return applyPatch(jsonPatch, obj); } + public static T applyJsonPatch(JsonPatch jsonPatch, T obj) throws JsonPatchException, IOException { + LOG.debug("Patch details - jsonPatch:{}, obj:{}", jsonPatch, obj ); + return applyPatch(jsonPatch, obj); + } + @SuppressWarnings("unchecked") public static T applyPatch(JsonPatch jsonPatch, T obj) throws JsonPatchException, JsonProcessingException { Preconditions.checkNotNull(jsonPatch);