From 93d753553925d60ba9c4264c3aab635036720cc1 Mon Sep 17 00:00:00 2001 From: Andrea Turli Date: Wed, 27 Jan 2016 12:46:41 +0100 Subject: [PATCH] More fixes to support jackson 2 - adjust BrooklynJacksonSerializer to use jackson 2 api - fix web.xml for rest-api and rest-client --- brooklyn-server/parent/pom.xml | 5 ++ .../brooklyn/rest/api/ApplicationApi.java | 3 +- .../brooklyn/rest/domain/EntityDetail.java | 40 ++------- .../brooklyn/rest/domain/TaskSummary.java | 34 ++++---- .../rest-api/src/main/webapp/WEB-INF/web.xml | 4 +- .../src/test/webapp/WEB-INF/web.xml | 2 +- brooklyn-server/rest/rest-server/pom.xml | 5 +- .../rest/resources/ApplicationResource.java | 83 ++++++++++++------- .../json/BrooklynJacksonJsonProvider.java | 21 ++--- .../json/ConfigurableSerializerProvider.java | 40 ++++----- ...ErrorAndToStringUnknownTypeSerializer.java | 28 +++---- .../src/main/webapp/WEB-INF/web.xml | 2 +- .../brooklyn/rest/domain/ApplicationTest.java | 17 ++-- 13 files changed, 138 insertions(+), 146 deletions(-) diff --git a/brooklyn-server/parent/pom.xml b/brooklyn-server/parent/pom.xml index 89b17f8d2c..2b1f4a5577 100644 --- a/brooklyn-server/parent/pom.xml +++ b/brooklyn-server/parent/pom.xml @@ -198,6 +198,11 @@ jackson-module-jaxb-annotations ${fasterxml.jackson.version} + + com.fasterxml.jackson.datatype + jackson-datatype-guava + ${fasterxml.jackson.version} + io.swagger swagger-annotations diff --git a/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java b/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java index 6b43608cae..cd8f22e56c 100644 --- a/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java +++ b/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java @@ -38,6 +38,7 @@ import org.apache.brooklyn.rest.domain.ApplicationSpec; import org.apache.brooklyn.rest.domain.ApplicationSummary; import org.apache.brooklyn.rest.domain.EntitySummary; +import org.apache.brooklyn.rest.domain.EntityDetail; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; @@ -55,7 +56,7 @@ public interface ApplicationApi { @ApiOperation( value = "Fetch display details for all applications and optionally selected additional entities" ) - public List fetch( + public List fetch( @ApiParam(value="Selected additional entity ID's to include, comma-separated", required=false) @DefaultValue("") @QueryParam("items") String items); diff --git a/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EntityDetail.java b/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EntityDetail.java index 5ec2a1581a..830c0b1742 100644 --- a/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EntityDetail.java +++ b/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EntityDetail.java @@ -22,10 +22,11 @@ import java.util.Map; import java.util.Objects; +import org.apache.brooklyn.core.entity.lifecycle.Lifecycle; + import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; public class EntityDetail extends EntitySummary { @@ -35,22 +36,25 @@ public class EntityDetail extends EntitySummary { @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY) private final List children; private final List groupIds; - private final Map members; + private final List> members; public EntityDetail( @JsonProperty("id") String id, @JsonProperty("parentId") String parentId, @JsonProperty("name") String name, @JsonProperty("type") String type, + @JsonProperty("serviceUp") Boolean serviceUp, + @JsonProperty("serviceState") Lifecycle serviceState, + @JsonProperty("iconUrl") String iconUrl, @JsonProperty("catalogItemId") String catalogItemId, @JsonProperty("children") List children, @JsonProperty("groupIds") List groupIds, - @JsonProperty("members") Map members) { + @JsonProperty("members") List> members) { super(id, name, type, catalogItemId, null); this.parentId = parentId; this.children = (children == null) ? ImmutableList.of() : ImmutableList.copyOf(children); this.groupIds = (groupIds == null) ? ImmutableList.of() : ImmutableList.copyOf(groupIds); - this.members = (members == null) ? ImmutableMap. of() : ImmutableMap.copyOf(members); + this.members = (members == null) ? ImmutableList.>of() : ImmutableList.copyOf(members); } public static long getSerialVersionUID() { @@ -69,34 +73,8 @@ public List getGroupIds() { return groupIds; } - public Map getMembers() { + public List> getMembers() { return members; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof EntityDetail)) return false; - if (!super.equals(o)) return false; - EntityDetail that = (EntityDetail) o; - return Objects.equals(parentId, that.parentId) && - Objects.equals(children, that.children) && - Objects.equals(groupIds, that.groupIds) && - Objects.equals(members, that.members); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), parentId, children, groupIds, members); - } - - @Override - public String toString() { - return "EntityDetail{" + - "parentId='" + parentId + '\'' + - ", children=" + children + - ", groupIds=" + groupIds + - ", members=" + members + - '}'; - } } diff --git a/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TaskSummary.java b/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TaskSummary.java index eef57e6516..6de384e855 100644 --- a/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TaskSummary.java +++ b/brooklyn-server/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TaskSummary.java @@ -52,8 +52,8 @@ public class TaskSummary implements HasId, Serializable { private final String currentStatus; private final Object result; - private final boolean isError; - private final boolean isCancelled; + private final boolean error; + private final boolean cancelled; private final List children; private final LinkWithMetadata submittedByTask; @@ -82,8 +82,8 @@ public TaskSummary( @JsonProperty("endTimeUtc") Long endTimeUtc, @JsonProperty("currentStatus") String currentStatus, @JsonProperty("result") Object result, - @JsonProperty("isError") boolean isError, - @JsonProperty("isCancelled") boolean isCancelled, + @JsonProperty("error") boolean error, + @JsonProperty("cancelled") boolean cancelled, @JsonProperty("children") List children, @JsonProperty("submittedByTask") LinkWithMetadata submittedByTask, @JsonProperty("blockingTask") LinkWithMetadata blockingTask, @@ -102,8 +102,8 @@ public TaskSummary( this.endTimeUtc = endTimeUtc; this.currentStatus = currentStatus; this.result = result; - this.isError = isError; - this.isCancelled = isCancelled; + this.error = error; + this.cancelled = cancelled; this.children = children; this.blockingDetails = blockingDetails; this.blockingTask = blockingTask; @@ -168,26 +168,26 @@ public Object getResult() { return result; } - /** @deprecated since 0.7.0 use {@link #isError} instead. */ + /** @deprecated since 0.7.0 use {@link #error} instead. */ @Deprecated @JsonIgnore public boolean getIsError() { - return isError; + return error; } - /** @deprecated since 0.7.0 use {@link #isCancelled} instead. */ + /** @deprecated since 0.7.0 use {@link #cancelled} instead. */ @Deprecated @JsonIgnore public boolean getIsCancelled() { - return isCancelled; + return cancelled; } public boolean isError() { - return isError; + return error; } public boolean isCancelled() { - return isCancelled; + return cancelled; } public List getChildren() { @@ -223,8 +223,8 @@ public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof TaskSummary)) return false; TaskSummary that = (TaskSummary) o; - return isError == that.isError && - isCancelled == that.isCancelled && + return error == that.error && + cancelled == that.cancelled && Objects.equals(id, that.id) && Objects.equals(displayName, that.displayName) && Objects.equals(entityId, that.entityId) && @@ -247,7 +247,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(id, displayName, entityId, entityDisplayName, description, tags, submitTimeUtc, startTimeUtc, endTimeUtc, currentStatus, result, isError, isCancelled, children, submittedByTask, blockingTask, blockingDetails, detailedStatus, streams, links); + return Objects.hash(id, displayName, entityId, entityDisplayName, description, tags, submitTimeUtc, startTimeUtc, endTimeUtc, currentStatus, result, error, cancelled, children, submittedByTask, blockingTask, blockingDetails, detailedStatus, streams, links); } @Override @@ -264,8 +264,8 @@ public String toString() { ", endTimeUtc=" + endTimeUtc + ", currentStatus='" + currentStatus + '\'' + ", result=" + result + - ", isError=" + isError + - ", isCancelled=" + isCancelled + + ", error=" + error + + ", cancelled=" + cancelled + ", children=" + children + ", submittedByTask=" + submittedByTask + ", blockingTask=" + blockingTask + diff --git a/brooklyn-server/rest/rest-api/src/main/webapp/WEB-INF/web.xml b/brooklyn-server/rest/rest-api/src/main/webapp/WEB-INF/web.xml index 06331bd0aa..bab259bf0c 100644 --- a/brooklyn-server/rest/rest-api/src/main/webapp/WEB-INF/web.xml +++ b/brooklyn-server/rest/rest-api/src/main/webapp/WEB-INF/web.xml @@ -83,14 +83,14 @@ com.sun.jersey.config.property.packages - io.swagger.jaxrs.listing;org.codehaus.jackson.jaxrs;org.apache.brooklyn.rest.resources;org.apache.brooklyn.rest.util + io.swagger.jaxrs.listing;com.fasterxml.jackson.jaxrs;org.apache.brooklyn.rest.resources;org.apache.brooklyn.rest.util com.sun.jersey.config.property.classnames - org.codehaus.jackson.jaxrs.JacksonJsonProvider + com.fasterxml.jackson.jaxrs.JacksonJsonProvider com.sun.jersey.api.json.POJOMappingFeature diff --git a/brooklyn-server/rest/rest-client/src/test/webapp/WEB-INF/web.xml b/brooklyn-server/rest/rest-client/src/test/webapp/WEB-INF/web.xml index 83d76c0632..38b637a59c 100644 --- a/brooklyn-server/rest/rest-client/src/test/webapp/WEB-INF/web.xml +++ b/brooklyn-server/rest/rest-client/src/test/webapp/WEB-INF/web.xml @@ -84,7 +84,7 @@ org.apache.brooklyn.rest.apidoc.ApidocHelpMessageBodyWriter; org.apache.brooklyn.rest.util.FormMapProvider; - org.codehaus.jackson.jaxrs.JacksonJsonProvider; + com.fasterxml.jackson.jaxrs.JacksonJsonProvider; org.apache.brooklyn.rest.resources.ActivityResource; org.apache.brooklyn.rest.resources.ApidocResource; org.apache.brooklyn.rest.resources.ApplicationResource; diff --git a/brooklyn-server/rest/rest-server/pom.xml b/brooklyn-server/rest/rest-server/pom.xml index f208d8f6a9..9b36f69c7e 100644 --- a/brooklyn-server/rest/rest-server/pom.xml +++ b/brooklyn-server/rest/rest-server/pom.xml @@ -97,7 +97,10 @@ com.fasterxml.jackson.datatype jackson-datatype-guava - ${fasterxml.jackson.version} + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider com.sun.jersey diff --git a/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java index df92e1c7b0..d9c38b6077 100644 --- a/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java +++ b/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java @@ -25,6 +25,7 @@ import java.net.URI; import java.net.URISyntaxException; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -38,6 +39,7 @@ import org.apache.brooklyn.api.entity.Application; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.entity.Group; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.mgmt.Task; import org.apache.brooklyn.api.objs.BrooklynObject; @@ -58,9 +60,11 @@ import org.apache.brooklyn.core.sensor.Sensors; import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts; import org.apache.brooklyn.core.typereg.RegisteredTypes; +import org.apache.brooklyn.entity.group.AbstractGroup; import org.apache.brooklyn.rest.api.ApplicationApi; import org.apache.brooklyn.rest.domain.ApplicationSpec; import org.apache.brooklyn.rest.domain.ApplicationSummary; +import org.apache.brooklyn.rest.domain.EntityDetail; import org.apache.brooklyn.rest.domain.EntitySummary; import org.apache.brooklyn.rest.domain.TaskSummary; import org.apache.brooklyn.rest.filter.HaHotStateRequired; @@ -79,11 +83,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.base.Throwables; import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -95,53 +97,74 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements @Context private UriInfo uriInfo; - private ObjectNode entityBase(Entity entity) { - ObjectNode aRoot = mapper().createObjectNode(); - aRoot.put("name", entity.getDisplayName()); - aRoot.put("id", entity.getId()); - aRoot.put("type", entity.getEntityType().getName()); - + private EntityDetail fromEntity(Entity entity) { Boolean serviceUp = entity.getAttribute(Attributes.SERVICE_UP); - if (serviceUp!=null) aRoot.put("serviceUp", serviceUp); Lifecycle serviceState = entity.getAttribute(Attributes.SERVICE_STATE_ACTUAL); - if (serviceState!=null) aRoot.put("serviceState", serviceState.toString()); String iconUrl = entity.getIconUrl(); if (iconUrl!=null) { if (brooklyn().isUrlServerSideAndSafe(iconUrl)) // route to server if it is a server-side url iconUrl = EntityTransformer.entityUri(entity)+"/icon"; - aRoot.put("iconUrl", iconUrl); } - return aRoot; - } + List children = Lists.newArrayList(); + if (!entity.getChildren().isEmpty()) { + for (Entity child : entity.getChildren()) { + children.add(fromEntity(child)); + } + } - private JsonNode recursiveTreeFromEntity(Entity entity) { - ObjectNode aRoot = entityBase(entity); + String parentId = null; + if (entity.getParent()!= null) { + parentId = entity.getParent().getId(); + } + + List groupIds = Lists.newArrayList(); + if (!entity.groups().isEmpty()) { + groupIds.addAll(entitiesIdAsArray(entity.groups())); + } - if (!entity.getChildren().isEmpty()) - aRoot.put("children", childEntitiesRecursiveAsArray(entity)); + List> members = Lists.newArrayList(); + if (entity instanceof Group) { + // use attribute instead of method in case it is read-only + Collection memberEntities = entity.getAttribute(AbstractGroup.GROUP_MEMBERS); + if (memberEntities != null && !memberEntities.isEmpty()) + members.addAll(entitiesIdAndNameAsList(memberEntities)); + } - return aRoot; + return new EntityDetail(entity.getId(), parentId, entity.getDisplayName(), + entity.getEntityType().getName(), serviceUp, serviceState, iconUrl, entity.getCatalogItemId(), + children, groupIds, members); } - private ArrayNode childEntitiesRecursiveAsArray(Entity entity) { - ArrayNode node = mapper().createArrayNode(); - for (Entity e : entity.getChildren()) { + private List> entitiesIdAndNameAsList(Collection entities) { + List> members = Lists.newArrayList(); + for (Entity entity : entities) { if (Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) { - node.add(recursiveTreeFromEntity(e)); + members.add(ImmutableMap.of("id", entity.getId(), "name", entity.getDisplayName())); } } - return node; + return members; + } + + private List entitiesIdAsArray(Iterable entities) { + List ids = Lists.newArrayList(); + for (Entity entity : entities) { + if (Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) { + ids.add(entity.getId()); + } + } + return ids; } @Override - public List fetch(String entityIds) { - List result = Lists.newArrayList(); - for (Application application : mgmt().getApplications()) { - result.add(EntityTransformer.entitySummary(application)); + public List fetch(String entityIds) { + + List entitySummaries = Lists.newArrayList(); + for (Entity application : mgmt().getApplications()) { + entitySummaries.add(fromEntity(application)); } if (entityIds != null) { @@ -149,13 +172,13 @@ public List fetch(String entityIds) { Entity entity = mgmt().getEntityManager().getEntity(entityId.trim()); while (entity != null && entity.getParent() != null) { if (Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) { - result.add(EntityTransformer.entitySummary(entity)); + entitySummaries.add(fromEntity(entity)); } entity = entity.getParent(); } } } - return result; + return entitySummaries; } @Override diff --git a/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonJsonProvider.java b/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonJsonProvider.java index a45960daca..f6d2a08462 100644 --- a/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonJsonProvider.java +++ b/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonJsonProvider.java @@ -25,8 +25,8 @@ import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.ConfigKeys; +import org.apache.brooklyn.core.internal.BrooklynProperties; import org.apache.brooklyn.core.mgmt.ManagementContextInjectable; -import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; import org.apache.brooklyn.core.server.BrooklynServiceAttributes; import org.apache.brooklyn.rest.util.OsgiCompat; import org.slf4j.Logger; @@ -35,6 +35,7 @@ import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.guava.GuavaModule; import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; public class BrooklynJacksonJsonProvider extends JacksonJsonProvider implements ManagementContextInjectable { @@ -105,7 +106,7 @@ public static ObjectMapper findSharedObjectMapper(ServletContext servletContext, mapper = newPrivateObjectMapper(mgmt); log.debug("Storing new ObjectMapper against "+mgmt+" because no ServletContext available: "+mapper); - ((ManagementContextInternal)mgmt).getBrooklynProperties().put(key, mapper); + ((BrooklynProperties)mgmt.getConfig()).put(key, mapper); return mapper; } } @@ -134,28 +135,22 @@ public static ObjectMapper newPrivateObjectMapper(ManagementContext mgmt) { if (mgmt == null) { throw new IllegalStateException("No management context available for creating ObjectMapper"); } -/* - SerializationConfig defaultConfig = new ObjectMapper().getSerializationConfig(); - SerializationConfig sc = new SerializationConfig( - defaultConfig.getClassIntrospector() /* ObjectMapper.DEFAULT_INTROSPECTOR *, - defaultConfig.getAnnotationIntrospector() /* ObjectMapper.DEFAULT_ANNOTATION_INTROSPECTOR *, - new PossiblyStrictPreferringFieldsVisibilityChecker(), - null, null, TypeFactory.defaultInstance(), null); ConfigurableSerializerProvider sp = new ConfigurableSerializerProvider(); sp.setUnknownTypeSerializer(new ErrorAndToStringUnknownTypeSerializer()); - ObjectMapper mapper = new ObjectMapper(null, sp, null, sc, null); -*/ ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializerProvider(sp); + mapper.setVisibility(new PossiblyStrictPreferringFieldsVisibilityChecker()); + SimpleModule mapperModule = new SimpleModule("Brooklyn", new Version(0, 0, 0, "ignored")); new BidiSerialization.ManagementContextSerialization(mgmt).install(mapperModule); new BidiSerialization.EntitySerialization(mgmt).install(mapperModule); new BidiSerialization.LocationSerialization(mgmt).install(mapperModule); - mapperModule.addSerializer(new MultimapSerializer()); - mapper.registerModule(mapperModule); + mapper.registerModule(new GuavaModule()).registerModule(mapperModule); + return mapper; } diff --git a/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/ConfigurableSerializerProvider.java b/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/ConfigurableSerializerProvider.java index 12b978c5f8..a84c6955e9 100644 --- a/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/ConfigurableSerializerProvider.java +++ b/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/ConfigurableSerializerProvider.java @@ -23,65 +23,60 @@ import org.apache.brooklyn.util.exceptions.Exceptions; import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonStreamContext; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider; import com.fasterxml.jackson.databind.ser.SerializerFactory; /** allows the serializer-of-last-resort to be customized, ie used for unknown-types */ -/* -final class ConfigurableSerializerProvider extends StdSerializerProvider { - +final class ConfigurableSerializerProvider extends DefaultSerializerProvider { + + protected JsonSerializer unknownTypeSerializer; + public ConfigurableSerializerProvider() {} - - public ConfigurableSerializerProvider(SerializationConfig config) { - // NB: not usually necessary to pass config, as object mapper gets its own config set explicitly - this(config, new ConfigurableSerializerProvider(), null); + + @Override + public DefaultSerializerProvider createInstance(SerializationConfig config, SerializerFactory jsf) { + return new ConfigurableSerializerProvider(config, this, jsf); } - + public ConfigurableSerializerProvider(SerializationConfig config, ConfigurableSerializerProvider src, SerializerFactory jsf) { - super(config, src, jsf); + super(src, config, jsf); unknownTypeSerializer = src.unknownTypeSerializer; } - - protected StdSerializerProvider createInstance(SerializationConfig config, SerializerFactory jsf) { - return new ConfigurableSerializerProvider(config, this, jsf); - } - protected JsonSerializer unknownTypeSerializer; - public JsonSerializer getUnknownTypeSerializer(Class unknownType) { if (unknownTypeSerializer!=null) return unknownTypeSerializer; return super.getUnknownTypeSerializer(unknownType); } - + public void setUnknownTypeSerializer(JsonSerializer unknownTypeSerializer) { this.unknownTypeSerializer = unknownTypeSerializer; } @Override - protected void _serializeValue(JsonGenerator jgen, Object value) throws IOException, JsonProcessingException { + public void serializeValue(JsonGenerator jgen, Object value) throws IOException { JsonStreamContext ctxt = jgen.getOutputContext(); try { - super._serializeValue(jgen, value); + super.serializeValue(jgen, value); } catch (Exception e) { onSerializationException(ctxt, jgen, value, e); } } @Override - protected void _serializeValue(JsonGenerator jgen, Object value, JavaType rootType) throws IOException, JsonProcessingException { + public void serializeValue(JsonGenerator jgen, Object value, JavaType rootType) throws IOException { JsonStreamContext ctxt = jgen.getOutputContext(); try { - super._serializeValue(jgen, value, rootType); + super.serializeValue(jgen, value, rootType); } catch (Exception e) { onSerializationException(ctxt, jgen, value, e); } } - protected void onSerializationException(JsonStreamContext ctxt, JsonGenerator jgen, Object value, Exception e) throws IOException, JsonProcessingException { + protected void onSerializationException(JsonStreamContext ctxt, JsonGenerator jgen, Object value, Exception e) throws IOException { Exceptions.propagateIfFatal(e); JsonSerializer unknownTypeSerializer = getUnknownTypeSerializer(value.getClass()); @@ -92,4 +87,3 @@ protected void onSerializationException(JsonStreamContext ctxt, JsonGenerator jg } } } -*/ diff --git a/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/ErrorAndToStringUnknownTypeSerializer.java b/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/ErrorAndToStringUnknownTypeSerializer.java index e008be067f..e529ec9c03 100644 --- a/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/ErrorAndToStringUnknownTypeSerializer.java +++ b/brooklyn-server/rest/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/ErrorAndToStringUnknownTypeSerializer.java @@ -30,9 +30,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonStreamContext; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.SerializerProvider; @@ -41,30 +39,30 @@ /** * for non-json-serializable classes (quite a lot of them!) simply provide a sensible error message and a toString. - * TODO maybe we want to attempt to serialize fields instead? (but being careful not to be self-referential!) + * TODO maybe we want to attempt to serialize fields instead? (but being careful not to be self-referential!) */ public class ErrorAndToStringUnknownTypeSerializer extends UnknownSerializer { - + private static final Logger log = LoggerFactory.getLogger(ErrorAndToStringUnknownTypeSerializer.class); private static Set WARNED_CLASSES = Collections.synchronizedSet(MutableSet.of()); - + @Override - public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException { if (BidiSerialization.isStrictSerialization()) throw new JsonMappingException("Cannot serialize object containing "+value.getClass().getName()+" when strict serialization requested"); serializeFromError(jgen.getOutputContext(), null, value, jgen, provider); } - public void serializeFromError(JsonStreamContext ctxt, @Nullable Exception error, Object value, JsonGenerator jgen, SerializerProvider configurableSerializerProvider) throws JsonGenerationException, IOException { + public void serializeFromError(JsonStreamContext ctxt, @Nullable Exception error, Object value, JsonGenerator jgen, SerializerProvider configurableSerializerProvider) throws IOException { if (log.isDebugEnabled()) log.debug("Recovering from json serialization error, serializing "+value+": "+error); - + if (BidiSerialization.isStrictSerialization()) throw new JsonMappingException("Cannot serialize " + (ctxt!=null && !ctxt.inRoot() ? "object containing " : "") + value.getClass().getName()+" when strict serialization requested"); - + if (WARNED_CLASSES.add(value.getClass().getCanonicalName())) { log.warn("Standard serialization not possible for "+value.getClass()+" ("+value+")", error); } @@ -74,12 +72,12 @@ public void serializeFromError(JsonStreamContext ctxt, @Nullable Exception error // without this, when serializing the large (1.5M) Server json object from BrooklynJacksonSerializerTest creates invalid json, // containing: "foo":false,"{"error":true,... jgen.flush(); - + boolean createObject = !newCtxt.inObject() || newCtxt.getCurrentName()!=null; if (createObject) { jgen.writeStartObject(); } - + if (allowEmpty(value.getClass())) { // write nothing } else { @@ -100,16 +98,16 @@ public void serializeFromError(JsonStreamContext ctxt, @Nullable Exception error jgen.writeFieldName("causedByError"); jgen.writeString(error.toString()); } - + } - + if (createObject) { jgen.writeEndObject(); } - + while (newCtxt!=null && !newCtxt.equals(ctxt)) { if (jgen.getOutputContext().inArray()) { jgen.writeEndArray(); continue; } - if (jgen.getOutputContext().inObject()) { jgen.writeEndObject(); continue; } + if (jgen.getOutputContext().inObject()) { jgen.writeEndObject(); continue; } break; } diff --git a/brooklyn-server/rest/rest-server/src/main/webapp/WEB-INF/web.xml b/brooklyn-server/rest/rest-server/src/main/webapp/WEB-INF/web.xml index 1c44b025d7..ae98ff61ca 100644 --- a/brooklyn-server/rest/rest-server/src/main/webapp/WEB-INF/web.xml +++ b/brooklyn-server/rest/rest-server/src/main/webapp/WEB-INF/web.xml @@ -91,7 +91,7 @@ io.swagger.jaxrs.listing.SwaggerSerializers; org.apache.brooklyn.rest.util.FormMapProvider; - org.codehaus.jackson.jaxrs.JacksonJsonProvider; + com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; org.apache.brooklyn.rest.resources.ActivityResource; org.apache.brooklyn.rest.resources.ApidocResource; org.apache.brooklyn.rest.resources.ApplicationResource; diff --git a/brooklyn-server/rest/rest-server/src/test/java/org/apache/brooklyn/rest/domain/ApplicationTest.java b/brooklyn-server/rest/rest-server/src/test/java/org/apache/brooklyn/rest/domain/ApplicationTest.java index 7e9c910c29..8708fb194b 100644 --- a/brooklyn-server/rest/rest-server/src/test/java/org/apache/brooklyn/rest/domain/ApplicationTest.java +++ b/brooklyn-server/rest/rest-server/src/test/java/org/apache/brooklyn/rest/domain/ApplicationTest.java @@ -41,7 +41,7 @@ public class ApplicationTest { final EntitySpec entitySpec = new EntitySpec("Vanilla Java App", "org.apache.brooklyn.entity.java.VanillaJavaApp", - ImmutableMap.of( + ImmutableMap.of( "initialSize", "1", "creationScriptUrl", "http://my.brooklyn.io/storage/foo.sql")); @@ -50,20 +50,15 @@ public class ApplicationTest { .locations(ImmutableSet.of("/v1/locations/1")) .build(); - final ApplicationSummary application = new ApplicationSummary(null, applicationSpec, Status.STARTING, null); + final Map links = ImmutableMap.of( + "self", URI.create("/v1/applications/" + applicationSpec.getName()), + "entities", URI.create("fixtures/entity-summary-list.json")); + final ApplicationSummary application = new ApplicationSummary("myapp_id", applicationSpec, Status.STARTING, links); @SuppressWarnings("serial") @Test public void testSerializeToJSON() throws IOException { - ApplicationSummary application1 = new ApplicationSummary("myapp_id", applicationSpec, Status.STARTING, null) { - @Override - public Map getLinks() { - return ImmutableMap.of( - "self", URI.create("/v1/applications/" + applicationSpec.getName()), - "entities", URI.create("fixtures/entity-summary-list.json")); - } - }; - assertEquals(asJson(application1), jsonFixture("fixtures/application.json")); + assertEquals(asJson(application), jsonFixture("fixtures/application.json")); } @Test