@Override public void serialize(Item item, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeStartArray(); jgen.writeStartObject(); jgen.writeStringField("id", "i_" + String.valueOf(item.getId())); jgen.writeObjectField("title", item.getName()); jgen.writeObjectField("type", item.getType()); String imagePath = "i_image_" + item.getId() + "." + item.getImage().getExtention(); jgen.writeObjectFieldStart("image"); jgen.writeObjectField("type", item.getImage().getType()); jgen.writeObjectField("path", imagePath); jgen.writeEndObject(); jgen.writeObjectFieldStart("values"); jgen.writeStringField("productName", item.getName()); jgen.writeStringField("imageFullPath", imagePath); for (Description description : item.getDescription()) { if (description.getDescription().size() > 1) { jgen.writeArrayFieldStart(description.getValue().getKey()); for (String desc : description.getDescription()) jgen.writeString(desc); jgen.writeEndArray(); } else jgen.writeStringField( description.getValue().getKey(), (description.getDescription().size() == 0) ? "" : description.getDescription().get(0)); } jgen.writeEndObject(); jgen.writeEndObject(); jgen.writeEndArray(); }
@Override public void serialize( final GraphSONVertex directionalVertex, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException, JsonGenerationException { final Vertex vertex = directionalVertex.getVertexToSerialize(); jsonGenerator.writeStartObject(); jsonGenerator.writeObjectField(GraphSONTokens.ID, vertex.getId()); jsonGenerator.writeStringField(GraphSONTokens.LABEL, vertex.getLabel()); jsonGenerator.writeStringField(GraphSONTokens.TYPE, GraphSONTokens.VERTEX); if (normalize) { jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES); vertex .getProperties() .values() .stream() .sorted(Comparators.PROPERTY_COMPARATOR) .forEachOrdered( FunctionUtils.wrapConsumer( e -> jsonGenerator.writeObjectField(e.getKey(), e.get()))); jsonGenerator.writeEndObject(); } else { jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES); vertex .getProperties() .values() .forEach( FunctionUtils.wrapConsumer( e -> jsonGenerator.writeObjectField(e.getKey(), e.get()))); jsonGenerator.writeEndObject(); } if (directionalVertex.getDirection() == Direction.BOTH || directionalVertex.getDirection() == Direction.OUT) { jsonGenerator.writeArrayFieldStart(GraphSONTokens.OUT); if (normalize) vertex .outE() .order(Comparators.HELD_EDGE_COMPARATOR) .forEach(FunctionUtils.wrapConsumer(jsonGenerator::writeObject)); else vertex.outE().forEach(FunctionUtils.wrapConsumer(jsonGenerator::writeObject)); jsonGenerator.writeEndArray(); } if (directionalVertex.getDirection() == Direction.BOTH || directionalVertex.getDirection() == Direction.IN) { jsonGenerator.writeArrayFieldStart(GraphSONTokens.IN); if (normalize) vertex .inE() .order(Comparators.HELD_EDGE_COMPARATOR) .forEach(FunctionUtils.wrapConsumer(jsonGenerator::writeObject)); else vertex.inE().forEach(FunctionUtils.wrapConsumer(jsonGenerator::writeObject)); jsonGenerator.writeEndArray(); } jsonGenerator.writeEndObject(); }
/** * "hotspots": [{ * * <p>"id": "test_1", * * <p>"anchor": { "geolocation": { "lat": 52.3729, "lon": 4.93 } }, * * <p>"text": { "title": "The Layar Office", "description": "The Location of the Layar Office", * "footnote": "Powered by Layar" }, * * <p>"imageURL": "http:\/\/custom.layar.nl\/layarimage.jpeg", } * * <p>] * * <p>See http://layar.com/documentation/browser/api/getpois-response/hotspots/ * * @param generator * @param hotspots2 * @throws IOException * @throws JsonGenerationException */ private void createHotspots(JsonGenerator generator) throws JsonGenerationException, IOException { generator.writeFieldName("hotspots"); generator.writeStartArray(); for (Hotspot poi : this.hotspots) { generator.writeStartObject(); generator.writeStringField("id", poi.id); // generator.writeFieldName("actions"); // generator.writeStartArray(); // if (layarPOI.actions != null) { // for (final LayarAction layarAction : layarPOI.actions) { // layarAction.toJSON(generator); // } // } // generator.writeEndArray(); generator.writeObjectFieldStart("anchor"); generator.writeObjectFieldStart("geolocation"); generator.writeNumberField("lat", poi.lat); generator.writeNumberField("lon", poi.lon); generator.writeNumberField("alt", poi.alt); generator.writeEndObject(); generator.writeEndObject(); // generator.writeNumberField("distance", layarPOI.distance); // generator.writeNumberField("type", layarPOI.type); // generator.writeStringField("title", layarPOI.title); generator.writeObjectFieldStart("text"); generator.writeStringField("title", poi.title); generator.writeStringField("description", poi.description); generator.writeStringField("footnote", "Service URL: ..."); generator.writeEndObject(); generator.writeStringField("attribution", poi.attribution); if (poi.imageURL != null) { generator.writeStringField("imageURL", poi.imageURL.toString()); } else { generator.writeNullField("imageURL"); } generator.writeEndObject(); } generator.writeEndArray(); }
private void _serialise(final HyperLogLogPlus hyperLogLogPlus, final JsonGenerator jsonGenerator) throws IOException { jsonGenerator.writeObjectFieldStart("hyperLogLogPlus"); jsonGenerator.writeObjectField( HyperLogLogPlusJsonConstants.HYPER_LOG_LOG_PLUS_SKETCH_BYTES_FIELD, hyperLogLogPlus.getBytes()); jsonGenerator.writeNumberField( HyperLogLogPlusJsonConstants.CARDINALITY_FIELD, hyperLogLogPlus.cardinality()); jsonGenerator.writeEndObject(); }
private void addServiceData(JsonGenerator json, ServiceInstance localService) throws IOException { json.writeObjectFieldStart("origin"); json.writeStringField("host", localService.getHost()); json.writeNumberField("port", localService.getPort()); json.writeStringField("serviceId", localService.getServiceId()); if (this.properties.isSendId()) { json.writeStringField("id", this.context.getId()); } json.writeEndObject(); }
@Override protected ModelAndView handleRequestInternal( final HttpServletRequest request, final HttpServletResponse response) throws Exception { String accessToken = request.getParameter(OAuthConstants.ACCESS_TOKEN); if (StringUtils.isBlank(accessToken)) { final String authHeader = request.getHeader("Authorization"); if (StringUtils.isNotBlank(authHeader) && authHeader.toLowerCase().startsWith(OAuthConstants.BEARER_TOKEN.toLowerCase() + ' ')) { accessToken = authHeader.substring(OAuthConstants.BEARER_TOKEN.length() + 1); } } LOGGER.debug("{} : {}", OAuthConstants.ACCESS_TOKEN, accessToken); try (final JsonGenerator jsonGenerator = this.jsonFactory.createJsonGenerator(response.getWriter())) { response.setContentType("application/json"); // accessToken is required if (StringUtils.isBlank(accessToken)) { LOGGER.error("Missing {}", OAuthConstants.ACCESS_TOKEN); jsonGenerator.writeStartObject(); jsonGenerator.writeStringField("error", OAuthConstants.MISSING_ACCESS_TOKEN); jsonGenerator.writeEndObject(); return null; } // get ticket granting ticket final TicketGrantingTicket ticketGrantingTicket = (TicketGrantingTicket) this.ticketRegistry.getTicket(accessToken); if (ticketGrantingTicket == null || ticketGrantingTicket.isExpired()) { LOGGER.error("expired accessToken : {}", accessToken); jsonGenerator.writeStartObject(); jsonGenerator.writeStringField("error", OAuthConstants.EXPIRED_ACCESS_TOKEN); jsonGenerator.writeEndObject(); return null; } // generate profile : identifier + attributes final Principal principal = ticketGrantingTicket.getAuthentication().getPrincipal(); jsonGenerator.writeStartObject(); jsonGenerator.writeStringField(ID, principal.getId()); jsonGenerator.writeObjectFieldStart(ATTRIBUTES); final Map<String, Object> attributes = principal.getAttributes(); for (final Map.Entry<String, Object> entry : attributes.entrySet()) { // jsonGenerator.writeStartObject(); jsonGenerator.writeObjectField(entry.getKey(), entry.getValue()); // jsonGenerator.writeEndObject(); } // jsonGenerator.writeEndArray(); jsonGenerator.writeEndObject(); return null; } finally { response.flushBuffer(); } }
@Override public void serialize(Record record, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeStartObject(); jgen.writeStringField("id", record.getId()); jgen.writeStringField("type", record.getType()); jgen.writeStringField("creationDate", record.getTime().toString()); jgen.writeObjectFieldStart("fields"); for (Map.Entry<String, Field> entry : record.getFieldsEntrySet()) { // retrieve event field String fieldName = entry.getKey(); Field field = entry.getValue(); Object fieldValue = field.getRawValue(); String fieldType = field.getType().toString(); // dump event field as record attribute try { switch (fieldType.toLowerCase()) { case "string": jgen.writeStringField(fieldName, (String) fieldValue); break; case "integer": jgen.writeNumberField(fieldName, (int) fieldValue); break; case "long": jgen.writeNumberField(fieldName, (long) fieldValue); break; case "float": jgen.writeNumberField(fieldName, (float) fieldValue); break; case "double": jgen.writeNumberField(fieldName, (double) fieldValue); break; case "boolean": jgen.writeBooleanField(fieldName, (boolean) fieldValue); break; default: jgen.writeObjectField(fieldName, fieldValue); break; } } catch (Exception ex) { logger.debug("exception while serializing field {}", field); } } jgen.writeEndObject(); jgen.writeEndObject(); }
@Test public void writeJSONViaLowerlevelLibs() throws IOException { final StringWriter writer = new StringWriter(); final ObjectMapper mapper = new ObjectMapper(); final JsonGenerator jgen = mapper.getFactory().createGenerator(writer); jgen.writeStartObject(); jgen.writeStringField( "odata.type", "Microsoft.Test.OData.Services.AstoriaDefaultService.Customer"); jgen.writeStringField("*****@*****.**", "Edm.String"); jgen.writeStringField("Name", "A name"); jgen.writeStringField("*****@*****.**", "Edm.Int32"); jgen.writeNumberField("CustomerId", 0); jgen.writeArrayFieldStart("BackupContactInfo"); jgen.writeStartObject(); jgen.writeArrayFieldStart("AlternativeNames"); jgen.writeString("myname"); jgen.writeEndArray(); jgen.writeArrayFieldStart("EmailBag"); jgen.writeString("*****@*****.**"); jgen.writeEndArray(); jgen.writeObjectFieldStart("ContactAlias"); jgen.writeStringField( "odata.type", "Microsoft.Test.OData.Services.AstoriaDefaultService.Aliases"); jgen.writeArrayFieldStart("AlternativeNames"); jgen.writeString("myAlternativeName"); jgen.writeEndArray(); jgen.writeEndObject(); jgen.writeEndObject(); jgen.writeEndArray(); jgen.writeEndObject(); jgen.flush(); assertFalse(writer.toString().isEmpty()); }
@Override public void serialize( BulkIndexOperationHeader bulkIndexOperationHeader, JsonGenerator json, SerializerProvider provider) throws IOException { json.writeStartObject(); json.writeObjectFieldStart("index"); if (bulkIndexOperationHeader.index != null) { json.writeStringField("_index", bulkIndexOperationHeader.index); } if (bulkIndexOperationHeader.type != null) { json.writeStringField("_type", bulkIndexOperationHeader.type); } json.writeEndObject(); json.writeEndObject(); }
private void writeActionDescriptors( JsonGenerator jgen, String currentVocab, List<ActionDescriptor> actionDescriptors) throws IOException, IntrospectionException { for (ActionDescriptor actionDescriptor : actionDescriptors) { jgen.writeStartObject(); // begin a hydra:Operation final String semanticActionType = actionDescriptor.getSemanticActionType(); if (semanticActionType != null) { jgen.writeStringField("@type", semanticActionType); } jgen.writeStringField("hydra:method", actionDescriptor.getHttpMethod()); final ActionInputParameter requestBodyInputParameter = actionDescriptor.getRequestBody(); if (requestBodyInputParameter != null) { jgen.writeObjectFieldStart("hydra:expects"); // begin hydra:expects final Class<?> clazz = requestBodyInputParameter.getParameterType(); final Expose classExpose = clazz.getAnnotation(Expose.class); final String typeName; if (classExpose != null) { typeName = classExpose.value(); } else { typeName = requestBodyInputParameter.getParameterType().getSimpleName(); } jgen.writeStringField("@type", typeName); jgen.writeArrayFieldStart("hydra:supportedProperty"); // begin hydra:supportedProperty // TODO check need for actionDescriptor and requestBodyInputParameter here: recurseSupportedProperties( jgen, currentVocab, clazz, actionDescriptor, requestBodyInputParameter, requestBodyInputParameter.getCallValue()); jgen.writeEndArray(); // end hydra:supportedProperty jgen.writeEndObject(); // end hydra:expects } jgen.writeEndObject(); // end hydra:Operation } }
@Override public void serialize(MatchResult value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeStartObject(); writeNumberField(jgen, "score", value.getScore()); writeNumberField(jgen, "kills", value.getKills()); if (value.getMatch() != null) { writeNumberField(jgen, "cdate", value.getMatch().getCdate().getTime()); writeNumberField(jgen, "lives", value.getMatch().getLives()); writeStringField(jgen, "state", value.getMatch().getState().name()); writeBooleanField(jgen, "victory", value.getMatch().getVictory()); if (value.getMatch().getMap() != null) { Map map = value.getMatch().getMap(); jgen.writeObjectFieldStart("map"); writeNumberField(jgen, "id", map.getId()); writeStringField(jgen, "name", map.getName()); writeNumberField(jgen, "lives", map.getLives()); jgen.writeEndObject(); } } jgen.writeEndObject(); }
@Override public void toJson(JsonGenerator gen) throws IOException { gen.writeStartObject(); // common tags gen.writeObjectFieldStart("tags"); for (Tag tag : tags) { gen.writeStringField( ValidCharacters.toValidCharset(tag.getKey()), ValidCharacters.toValidCharset(tag.getValue())); } gen.writeEndObject(); gen.writeArrayFieldStart("metrics"); for (AtlasMetric m : metrics) { m.toJson(gen); } gen.writeEndArray(); gen.writeEndObject(); gen.flush(); }
@Override public String handleRequest(ExecutionJobVertex jobVertex, Map<String, String> params) throws Exception { // Build a map that groups tasks by TaskManager Map<String, List<ExecutionVertex>> taskManagerVertices = new HashMap<>(); for (ExecutionVertex vertex : jobVertex.getTaskVertices()) { TaskManagerLocation location = vertex.getCurrentAssignedResourceLocation(); String taskManager = location == null ? "(unassigned)" : location.getHostname() + ":" + location.dataPort(); List<ExecutionVertex> vertices = taskManagerVertices.get(taskManager); if (vertices == null) { vertices = new ArrayList<ExecutionVertex>(); taskManagerVertices.put(taskManager, vertices); } vertices.add(vertex); } // Build JSON response final long now = System.currentTimeMillis(); StringWriter writer = new StringWriter(); JsonGenerator gen = JsonFactory.jacksonFactory.createGenerator(writer); gen.writeStartObject(); gen.writeStringField("id", jobVertex.getJobVertexId().toString()); gen.writeStringField("name", jobVertex.getJobVertex().getName()); gen.writeNumberField("now", now); gen.writeArrayFieldStart("taskmanagers"); for (Entry<String, List<ExecutionVertex>> entry : taskManagerVertices.entrySet()) { String host = entry.getKey(); List<ExecutionVertex> taskVertices = entry.getValue(); int[] tasksPerState = new int[ExecutionState.values().length]; long startTime = Long.MAX_VALUE; long endTime = 0; boolean allFinished = true; LongCounter tmReadBytes = new LongCounter(); LongCounter tmWriteBytes = new LongCounter(); LongCounter tmReadRecords = new LongCounter(); LongCounter tmWriteRecords = new LongCounter(); for (ExecutionVertex vertex : taskVertices) { final ExecutionState state = vertex.getExecutionState(); tasksPerState[state.ordinal()]++; // take the earliest start time long started = vertex.getStateTimestamp(ExecutionState.DEPLOYING); if (started > 0) { startTime = Math.min(startTime, started); } allFinished &= state.isTerminal(); endTime = Math.max(endTime, vertex.getStateTimestamp(state)); Map<AccumulatorRegistry.Metric, Accumulator<?, ?>> metrics = vertex.getCurrentExecutionAttempt().getFlinkAccumulators(); if (metrics != null) { LongCounter readBytes = (LongCounter) metrics.get(AccumulatorRegistry.Metric.NUM_BYTES_IN); tmReadBytes.merge(readBytes); LongCounter writeBytes = (LongCounter) metrics.get(AccumulatorRegistry.Metric.NUM_BYTES_OUT); tmWriteBytes.merge(writeBytes); LongCounter readRecords = (LongCounter) metrics.get(AccumulatorRegistry.Metric.NUM_RECORDS_IN); tmReadRecords.merge(readRecords); LongCounter writeRecords = (LongCounter) metrics.get(AccumulatorRegistry.Metric.NUM_RECORDS_OUT); tmWriteRecords.merge(writeRecords); } } long duration; if (startTime < Long.MAX_VALUE) { if (allFinished) { duration = endTime - startTime; } else { endTime = -1L; duration = now - startTime; } } else { startTime = -1L; endTime = -1L; duration = -1L; } ExecutionState jobVertexState = ExecutionJobVertex.getAggregateJobVertexState(tasksPerState, taskVertices.size()); gen.writeStartObject(); gen.writeStringField("host", host); gen.writeStringField("status", jobVertexState.name()); gen.writeNumberField("start-time", startTime); gen.writeNumberField("end-time", endTime); gen.writeNumberField("duration", duration); gen.writeObjectFieldStart("metrics"); gen.writeNumberField("read-bytes", tmReadBytes.getLocalValuePrimitive()); gen.writeNumberField("write-bytes", tmWriteBytes.getLocalValuePrimitive()); gen.writeNumberField("read-records", tmReadRecords.getLocalValuePrimitive()); gen.writeNumberField("write-records", tmWriteRecords.getLocalValuePrimitive()); gen.writeEndObject(); gen.writeObjectFieldStart("status-counts"); for (ExecutionState state : ExecutionState.values()) { gen.writeNumberField(state.name(), tasksPerState[state.ordinal()]); } gen.writeEndObject(); gen.writeEndObject(); } gen.writeEndArray(); gen.writeEndObject(); gen.close(); return writer.toString(); }
private String getCollapserJson(final HystrixCollapserMetrics collapserMetrics) throws IOException { HystrixCollapserKey key = collapserMetrics.getCollapserKey(); StringWriter jsonString = new StringWriter(); JsonGenerator json = jsonFactory.createJsonGenerator(jsonString); json.writeStartObject(); json.writeStringField("type", "HystrixCollapser"); json.writeStringField("name", key.name()); json.writeNumberField("currentTime", System.currentTimeMillis()); safelyWriteNumberField( json, "rollingCountRequestsBatched", new Func0<Long>() { @Override public Long call() { return collapserMetrics.getRollingCount(HystrixEventType.Collapser.ADDED_TO_BATCH); } }); safelyWriteNumberField( json, "rollingCountBatches", new Func0<Long>() { @Override public Long call() { return collapserMetrics.getRollingCount(HystrixEventType.Collapser.BATCH_EXECUTED); } }); safelyWriteNumberField( json, "rollingCountResponsesFromCache", new Func0<Long>() { @Override public Long call() { return collapserMetrics.getRollingCount( HystrixEventType.Collapser.RESPONSE_FROM_CACHE); } }); // batch size percentiles json.writeNumberField("batchSize_mean", collapserMetrics.getBatchSizeMean()); json.writeObjectFieldStart("batchSize"); json.writeNumberField("25", collapserMetrics.getBatchSizePercentile(25)); json.writeNumberField("50", collapserMetrics.getBatchSizePercentile(50)); json.writeNumberField("75", collapserMetrics.getBatchSizePercentile(75)); json.writeNumberField("90", collapserMetrics.getBatchSizePercentile(90)); json.writeNumberField("95", collapserMetrics.getBatchSizePercentile(95)); json.writeNumberField("99", collapserMetrics.getBatchSizePercentile(99)); json.writeNumberField("99.5", collapserMetrics.getBatchSizePercentile(99.5)); json.writeNumberField("100", collapserMetrics.getBatchSizePercentile(100)); json.writeEndObject(); // shard size percentiles (commented-out for now) // json.writeNumberField("shardSize_mean", collapserMetrics.getShardSizeMean()); // json.writeObjectFieldStart("shardSize"); // json.writeNumberField("25", collapserMetrics.getShardSizePercentile(25)); // json.writeNumberField("50", collapserMetrics.getShardSizePercentile(50)); // json.writeNumberField("75", collapserMetrics.getShardSizePercentile(75)); // json.writeNumberField("90", collapserMetrics.getShardSizePercentile(90)); // json.writeNumberField("95", collapserMetrics.getShardSizePercentile(95)); // json.writeNumberField("99", collapserMetrics.getShardSizePercentile(99)); // json.writeNumberField("99.5", collapserMetrics.getShardSizePercentile(99.5)); // json.writeNumberField("100", collapserMetrics.getShardSizePercentile(100)); // json.writeEndObject(); // json.writeNumberField("propertyValue_metricsRollingStatisticalWindowInMilliseconds", // collapserMetrics.getProperties().metricsRollingStatisticalWindowInMilliseconds().get()); json.writeBooleanField( "propertyValue_requestCacheEnabled", collapserMetrics.getProperties().requestCacheEnabled().get()); json.writeNumberField( "propertyValue_maxRequestsInBatch", collapserMetrics.getProperties().maxRequestsInBatch().get()); json.writeNumberField( "propertyValue_timerDelayInMilliseconds", collapserMetrics.getProperties().timerDelayInMilliseconds().get()); json.writeNumberField( "reportingHosts", 1); // this will get summed across all instances in a cluster json.writeEndObject(); json.close(); return jsonString.getBuffer().toString(); }
private String getCommandJson(final HystrixCommandMetrics commandMetrics) throws IOException { HystrixCommandKey key = commandMetrics.getCommandKey(); HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key); StringWriter jsonString = new StringWriter(); JsonGenerator json = jsonFactory.createGenerator(jsonString); json.writeStartObject(); json.writeStringField("type", "HystrixCommand"); json.writeStringField("name", key.name()); json.writeStringField("group", commandMetrics.getCommandGroup().name()); json.writeNumberField("currentTime", System.currentTimeMillis()); // circuit breaker if (circuitBreaker == null) { // circuit breaker is disabled and thus never open json.writeBooleanField("isCircuitBreakerOpen", false); } else { json.writeBooleanField("isCircuitBreakerOpen", circuitBreaker.isOpen()); } HealthCounts healthCounts = commandMetrics.getHealthCounts(); json.writeNumberField("errorPercentage", healthCounts.getErrorPercentage()); json.writeNumberField("errorCount", healthCounts.getErrorCount()); json.writeNumberField("requestCount", healthCounts.getTotalRequests()); // rolling counters safelyWriteNumberField( json, "rollingCountBadRequests", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.BAD_REQUEST); } }); safelyWriteNumberField( json, "rollingCountCollapsedRequests", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.COLLAPSED); } }); safelyWriteNumberField( json, "rollingCountEmit", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.EMIT); } }); safelyWriteNumberField( json, "rollingCountExceptionsThrown", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.EXCEPTION_THROWN); } }); safelyWriteNumberField( json, "rollingCountFailure", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.FAILURE); } }); safelyWriteNumberField( json, "rollingCountFallbackEmit", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.FALLBACK_EMIT); } }); safelyWriteNumberField( json, "rollingCountFallbackFailure", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.FALLBACK_FAILURE); } }); safelyWriteNumberField( json, "rollingCountFallbackMissing", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.FALLBACK_MISSING); } }); safelyWriteNumberField( json, "rollingCountFallbackRejection", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.FALLBACK_REJECTION); } }); safelyWriteNumberField( json, "rollingCountFallbackSuccess", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.FALLBACK_SUCCESS); } }); safelyWriteNumberField( json, "rollingCountResponsesFromCache", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.RESPONSE_FROM_CACHE); } }); safelyWriteNumberField( json, "rollingCountSemaphoreRejected", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.SEMAPHORE_REJECTED); } }); safelyWriteNumberField( json, "rollingCountShortCircuited", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.SHORT_CIRCUITED); } }); safelyWriteNumberField( json, "rollingCountSuccess", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.SUCCESS); } }); safelyWriteNumberField( json, "rollingCountThreadPoolRejected", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.THREAD_POOL_REJECTED); } }); safelyWriteNumberField( json, "rollingCountTimeout", new Func0<Long>() { @Override public Long call() { return commandMetrics.getRollingCount(HystrixEventType.TIMEOUT); } }); json.writeNumberField( "currentConcurrentExecutionCount", commandMetrics.getCurrentConcurrentExecutionCount()); json.writeNumberField( "rollingMaxConcurrentExecutionCount", commandMetrics.getRollingMaxConcurrentExecutions()); // latency percentiles json.writeNumberField("latencyExecute_mean", commandMetrics.getExecutionTimeMean()); json.writeObjectFieldStart("latencyExecute"); json.writeNumberField("0", commandMetrics.getExecutionTimePercentile(0)); json.writeNumberField("25", commandMetrics.getExecutionTimePercentile(25)); json.writeNumberField("50", commandMetrics.getExecutionTimePercentile(50)); json.writeNumberField("75", commandMetrics.getExecutionTimePercentile(75)); json.writeNumberField("90", commandMetrics.getExecutionTimePercentile(90)); json.writeNumberField("95", commandMetrics.getExecutionTimePercentile(95)); json.writeNumberField("99", commandMetrics.getExecutionTimePercentile(99)); json.writeNumberField("99.5", commandMetrics.getExecutionTimePercentile(99.5)); json.writeNumberField("100", commandMetrics.getExecutionTimePercentile(100)); json.writeEndObject(); // json.writeNumberField("latencyTotal_mean", commandMetrics.getTotalTimeMean()); json.writeObjectFieldStart("latencyTotal"); json.writeNumberField("0", commandMetrics.getTotalTimePercentile(0)); json.writeNumberField("25", commandMetrics.getTotalTimePercentile(25)); json.writeNumberField("50", commandMetrics.getTotalTimePercentile(50)); json.writeNumberField("75", commandMetrics.getTotalTimePercentile(75)); json.writeNumberField("90", commandMetrics.getTotalTimePercentile(90)); json.writeNumberField("95", commandMetrics.getTotalTimePercentile(95)); json.writeNumberField("99", commandMetrics.getTotalTimePercentile(99)); json.writeNumberField("99.5", commandMetrics.getTotalTimePercentile(99.5)); json.writeNumberField("100", commandMetrics.getTotalTimePercentile(100)); json.writeEndObject(); // property values for reporting what is actually seen by the command rather than what was set // somewhere HystrixCommandProperties commandProperties = commandMetrics.getProperties(); json.writeNumberField( "propertyValue_circuitBreakerRequestVolumeThreshold", commandProperties.circuitBreakerRequestVolumeThreshold().get()); json.writeNumberField( "propertyValue_circuitBreakerSleepWindowInMilliseconds", commandProperties.circuitBreakerSleepWindowInMilliseconds().get()); json.writeNumberField( "propertyValue_circuitBreakerErrorThresholdPercentage", commandProperties.circuitBreakerErrorThresholdPercentage().get()); json.writeBooleanField( "propertyValue_circuitBreakerForceOpen", commandProperties.circuitBreakerForceOpen().get()); json.writeBooleanField( "propertyValue_circuitBreakerForceClosed", commandProperties.circuitBreakerForceClosed().get()); json.writeBooleanField( "propertyValue_circuitBreakerEnabled", commandProperties.circuitBreakerEnabled().get()); json.writeStringField( "propertyValue_executionIsolationStrategy", commandProperties.executionIsolationStrategy().get().name()); json.writeNumberField( "propertyValue_executionIsolationThreadTimeoutInMilliseconds", commandProperties.executionTimeoutInMilliseconds().get()); json.writeNumberField( "propertyValue_executionTimeoutInMilliseconds", commandProperties.executionTimeoutInMilliseconds().get()); json.writeBooleanField( "propertyValue_executionIsolationThreadInterruptOnTimeout", commandProperties.executionIsolationThreadInterruptOnTimeout().get()); json.writeStringField( "propertyValue_executionIsolationThreadPoolKeyOverride", commandProperties.executionIsolationThreadPoolKeyOverride().get()); json.writeNumberField( "propertyValue_executionIsolationSemaphoreMaxConcurrentRequests", commandProperties.executionIsolationSemaphoreMaxConcurrentRequests().get()); json.writeNumberField( "propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests", commandProperties.fallbackIsolationSemaphoreMaxConcurrentRequests().get()); /* * The following are commented out as these rarely change and are verbose for streaming for something people don't change. * We could perhaps allow a property or request argument to include these. */ // json.put("propertyValue_metricsRollingPercentileEnabled", // commandProperties.metricsRollingPercentileEnabled().get()); // json.put("propertyValue_metricsRollingPercentileBucketSize", // commandProperties.metricsRollingPercentileBucketSize().get()); // json.put("propertyValue_metricsRollingPercentileWindow", // commandProperties.metricsRollingPercentileWindowInMilliseconds().get()); // json.put("propertyValue_metricsRollingPercentileWindowBuckets", // commandProperties.metricsRollingPercentileWindowBuckets().get()); // json.put("propertyValue_metricsRollingStatisticalWindowBuckets", // commandProperties.metricsRollingStatisticalWindowBuckets().get()); json.writeNumberField( "propertyValue_metricsRollingStatisticalWindowInMilliseconds", commandProperties.metricsRollingStatisticalWindowInMilliseconds().get()); json.writeBooleanField( "propertyValue_requestCacheEnabled", commandProperties.requestCacheEnabled().get()); json.writeBooleanField( "propertyValue_requestLogEnabled", commandProperties.requestLogEnabled().get()); json.writeNumberField( "reportingHosts", 1); // this will get summed across all instances in a cluster json.writeStringField("threadPool", commandMetrics.getThreadPoolKey().name()); json.writeEndObject(); json.close(); return jsonString.getBuffer().toString(); }
@Override public void serialize(CyNetworkView networkView, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.useDefaultPrettyPrinter(); jgen.writeStartObject(); jgen.writeStringField( CytoscapeJsNetworkModule.FORMAT_VERSION_TAG, CytoscapeJsNetworkModule.FORMAT_VERSION); jgen.writeStringField(CytoscapeJsNetworkModule.GENERATED_BY_TAG, "cytoscape-" + version); jgen.writeStringField( CytoscapeJsNetworkModule.TARGET_CYJS_VERSION_TAG, CytoscapeJsNetworkModule.CYTOSCAPEJS_VERSION); final CyNetwork network = networkView.getModel(); // Serialize network data table jgen.writeObjectFieldStart(DATA.getTag()); jgen.writeObject(network.getRow(network)); jgen.writeEndObject(); jgen.writeObjectFieldStart(ELEMENTS.getTag()); // Write array final List<CyNode> nodes = network.getNodeList(); final List<CyEdge> edges = network.getEdgeList(); jgen.writeArrayFieldStart(NODES.getTag()); for (final CyNode node : nodes) { jgen.writeStartObject(); // Data field jgen.writeObjectFieldStart(DATA.getTag()); jgen.writeStringField(ID.getTag(), node.getSUID().toString()); // Write CyRow in "data" field jgen.writeObject(network.getRow(node)); jgen.writeEndObject(); // Position and other visual props jgen.writeObject(networkView.getNodeView(node)); // Special case for cytoscape.js format: // - Selected jgen.writeBooleanField( CyNetwork.SELECTED, network.getRow(node).get(CyNetwork.SELECTED, Boolean.class)); jgen.writeEndObject(); } jgen.writeEndArray(); jgen.writeArrayFieldStart(EDGES.getTag()); for (final CyEdge edge : edges) { jgen.writeStartObject(); jgen.writeObjectFieldStart(DATA.getTag()); jgen.writeStringField(ID.getTag(), edge.getSUID().toString()); jgen.writeStringField(SOURCE.getTag(), edge.getSource().getSUID().toString()); jgen.writeStringField(TARGET.getTag(), edge.getTarget().getSUID().toString()); // Write CyRow in "data" field jgen.writeObject(network.getRow(edge)); jgen.writeEndObject(); // Special case for cytoscape.js format: // - Selected jgen.writeBooleanField( CyNetwork.SELECTED, network.getRow(edge).get(CyNetwork.SELECTED, Boolean.class)); jgen.writeEndObject(); } jgen.writeEndArray(); jgen.writeEndObject(); }
@Scheduled(fixedRateString = "${hystrix.stream.amqp.gatherRate:500}") public void gatherMetrics() { try { // command metrics Collection<HystrixCommandMetrics> instances = HystrixCommandMetrics.getInstances(); if (!instances.isEmpty()) { log.trace("gathering metrics size: " + instances.size()); } ServiceInstance localService = this.discoveryClient.getLocalServiceInstance(); for (HystrixCommandMetrics commandMetrics : instances) { HystrixCommandKey key = commandMetrics.getCommandKey(); HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key); StringWriter jsonString = new StringWriter(); JsonGenerator json = this.jsonFactory.createGenerator(jsonString); json.writeStartObject(); addServiceData(json, localService); json.writeObjectFieldStart("data"); json.writeStringField("type", "HystrixCommand"); String name = key.name(); if (this.properties.isPrefixMetricName()) { name = localService.getServiceId() + "." + name; } json.writeStringField("name", name); json.writeStringField("group", commandMetrics.getCommandGroup().name()); json.writeNumberField("currentTime", System.currentTimeMillis()); // circuit breaker if (circuitBreaker == null) { // circuit breaker is disabled and thus never open json.writeBooleanField("isCircuitBreakerOpen", false); } else { json.writeBooleanField("isCircuitBreakerOpen", circuitBreaker.isOpen()); } HystrixCommandMetrics.HealthCounts healthCounts = commandMetrics.getHealthCounts(); json.writeNumberField("errorPercentage", healthCounts.getErrorPercentage()); json.writeNumberField("errorCount", healthCounts.getErrorCount()); json.writeNumberField("requestCount", healthCounts.getTotalRequests()); // rolling counters json.writeNumberField( "rollingCountCollapsedRequests", commandMetrics.getRollingCount(HystrixRollingNumberEvent.COLLAPSED)); json.writeNumberField( "rollingCountExceptionsThrown", commandMetrics.getRollingCount(HystrixRollingNumberEvent.EXCEPTION_THROWN)); json.writeNumberField( "rollingCountFailure", commandMetrics.getRollingCount(HystrixRollingNumberEvent.FAILURE)); json.writeNumberField( "rollingCountFallbackFailure", commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_FAILURE)); json.writeNumberField( "rollingCountFallbackRejection", commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_REJECTION)); json.writeNumberField( "rollingCountFallbackSuccess", commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_SUCCESS)); json.writeNumberField( "rollingCountResponsesFromCache", commandMetrics.getRollingCount(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE)); json.writeNumberField( "rollingCountSemaphoreRejected", commandMetrics.getRollingCount(HystrixRollingNumberEvent.SEMAPHORE_REJECTED)); json.writeNumberField( "rollingCountShortCircuited", commandMetrics.getRollingCount(HystrixRollingNumberEvent.SHORT_CIRCUITED)); json.writeNumberField( "rollingCountSuccess", commandMetrics.getRollingCount(HystrixRollingNumberEvent.SUCCESS)); json.writeNumberField( "rollingCountThreadPoolRejected", commandMetrics.getRollingCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED)); json.writeNumberField( "rollingCountTimeout", commandMetrics.getRollingCount(HystrixRollingNumberEvent.TIMEOUT)); json.writeNumberField( "currentConcurrentExecutionCount", commandMetrics.getCurrentConcurrentExecutionCount()); // latency percentiles json.writeNumberField("latencyExecute_mean", commandMetrics.getExecutionTimeMean()); json.writeObjectFieldStart("latencyExecute"); json.writeNumberField("0", commandMetrics.getExecutionTimePercentile(0)); json.writeNumberField("25", commandMetrics.getExecutionTimePercentile(25)); json.writeNumberField("50", commandMetrics.getExecutionTimePercentile(50)); json.writeNumberField("75", commandMetrics.getExecutionTimePercentile(75)); json.writeNumberField("90", commandMetrics.getExecutionTimePercentile(90)); json.writeNumberField("95", commandMetrics.getExecutionTimePercentile(95)); json.writeNumberField("99", commandMetrics.getExecutionTimePercentile(99)); json.writeNumberField("99.5", commandMetrics.getExecutionTimePercentile(99.5)); json.writeNumberField("100", commandMetrics.getExecutionTimePercentile(100)); json.writeEndObject(); // json.writeNumberField("latencyTotal_mean", commandMetrics.getTotalTimeMean()); json.writeObjectFieldStart("latencyTotal"); json.writeNumberField("0", commandMetrics.getTotalTimePercentile(0)); json.writeNumberField("25", commandMetrics.getTotalTimePercentile(25)); json.writeNumberField("50", commandMetrics.getTotalTimePercentile(50)); json.writeNumberField("75", commandMetrics.getTotalTimePercentile(75)); json.writeNumberField("90", commandMetrics.getTotalTimePercentile(90)); json.writeNumberField("95", commandMetrics.getTotalTimePercentile(95)); json.writeNumberField("99", commandMetrics.getTotalTimePercentile(99)); json.writeNumberField("99.5", commandMetrics.getTotalTimePercentile(99.5)); json.writeNumberField("100", commandMetrics.getTotalTimePercentile(100)); json.writeEndObject(); // property values for reporting what is actually seen by the command // rather than what was set somewhere HystrixCommandProperties commandProperties = commandMetrics.getProperties(); json.writeNumberField( "propertyValue_circuitBreakerRequestVolumeThreshold", commandProperties.circuitBreakerRequestVolumeThreshold().get()); json.writeNumberField( "propertyValue_circuitBreakerSleepWindowInMilliseconds", commandProperties.circuitBreakerSleepWindowInMilliseconds().get()); json.writeNumberField( "propertyValue_circuitBreakerErrorThresholdPercentage", commandProperties.circuitBreakerErrorThresholdPercentage().get()); json.writeBooleanField( "propertyValue_circuitBreakerForceOpen", commandProperties.circuitBreakerForceOpen().get()); json.writeBooleanField( "propertyValue_circuitBreakerForceClosed", commandProperties.circuitBreakerForceClosed().get()); json.writeBooleanField( "propertyValue_circuitBreakerEnabled", commandProperties.circuitBreakerEnabled().get()); json.writeStringField( "propertyValue_executionIsolationStrategy", commandProperties.executionIsolationStrategy().get().name()); json.writeNumberField( "propertyValue_executionIsolationThreadTimeoutInMilliseconds", commandProperties.executionIsolationThreadTimeoutInMilliseconds().get()); json.writeBooleanField( "propertyValue_executionIsolationThreadInterruptOnTimeout", commandProperties.executionIsolationThreadInterruptOnTimeout().get()); json.writeStringField( "propertyValue_executionIsolationThreadPoolKeyOverride", commandProperties.executionIsolationThreadPoolKeyOverride().get()); json.writeNumberField( "propertyValue_executionIsolationSemaphoreMaxConcurrentRequests", commandProperties.executionIsolationSemaphoreMaxConcurrentRequests().get()); json.writeNumberField( "propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests", commandProperties.fallbackIsolationSemaphoreMaxConcurrentRequests().get()); // TODO /* * The following are commented out as these rarely change and are verbose * for streaming for something people don't change. We could perhaps allow * a property or request argument to include these. */ // json.put("propertyValue_metricsRollingPercentileEnabled", // commandProperties.metricsRollingPercentileEnabled().get()); // json.put("propertyValue_metricsRollingPercentileBucketSize", // commandProperties.metricsRollingPercentileBucketSize().get()); // json.put("propertyValue_metricsRollingPercentileWindow", // commandProperties.metricsRollingPercentileWindowInMilliseconds().get()); // json.put("propertyValue_metricsRollingPercentileWindowBuckets", // commandProperties.metricsRollingPercentileWindowBuckets().get()); // json.put("propertyValue_metricsRollingStatisticalWindowBuckets", // commandProperties.metricsRollingStatisticalWindowBuckets().get()); json.writeNumberField( "propertyValue_metricsRollingStatisticalWindowInMilliseconds", commandProperties.metricsRollingStatisticalWindowInMilliseconds().get()); json.writeBooleanField( "propertyValue_requestCacheEnabled", commandProperties.requestCacheEnabled().get()); json.writeBooleanField( "propertyValue_requestLogEnabled", commandProperties.requestLogEnabled().get()); json.writeNumberField("reportingHosts", 1); // this will get summed across // all instances in a cluster json.writeEndObject(); // end data attribute json.writeEndObject(); json.close(); // output this.jsonMetrics.add(jsonString.getBuffer().toString()); } // thread pool metrics for (HystrixThreadPoolMetrics threadPoolMetrics : HystrixThreadPoolMetrics.getInstances()) { HystrixThreadPoolKey key = threadPoolMetrics.getThreadPoolKey(); StringWriter jsonString = new StringWriter(); JsonGenerator json = this.jsonFactory.createGenerator(jsonString); json.writeStartObject(); addServiceData(json, localService); json.writeObjectFieldStart("data"); json.writeStringField("type", "HystrixThreadPool"); json.writeStringField("name", key.name()); json.writeNumberField("currentTime", System.currentTimeMillis()); json.writeNumberField( "currentActiveCount", threadPoolMetrics.getCurrentActiveCount().intValue()); json.writeNumberField( "currentCompletedTaskCount", threadPoolMetrics.getCurrentCompletedTaskCount().longValue()); json.writeNumberField( "currentCorePoolSize", threadPoolMetrics.getCurrentCorePoolSize().intValue()); json.writeNumberField( "currentLargestPoolSize", threadPoolMetrics.getCurrentLargestPoolSize().intValue()); json.writeNumberField( "currentMaximumPoolSize", threadPoolMetrics.getCurrentMaximumPoolSize().intValue()); json.writeNumberField("currentPoolSize", threadPoolMetrics.getCurrentPoolSize().intValue()); json.writeNumberField( "currentQueueSize", threadPoolMetrics.getCurrentQueueSize().intValue()); json.writeNumberField( "currentTaskCount", threadPoolMetrics.getCurrentTaskCount().longValue()); json.writeNumberField( "rollingCountThreadsExecuted", threadPoolMetrics.getRollingCountThreadsExecuted()); json.writeNumberField( "rollingMaxActiveThreads", threadPoolMetrics.getRollingMaxActiveThreads()); json.writeNumberField( "propertyValue_queueSizeRejectionThreshold", threadPoolMetrics.getProperties().queueSizeRejectionThreshold().get()); json.writeNumberField( "propertyValue_metricsRollingStatisticalWindowInMilliseconds", threadPoolMetrics .getProperties() .metricsRollingStatisticalWindowInMilliseconds() .get()); json.writeNumberField("reportingHosts", 1); // this will get summed across // all instances in a cluster json.writeEndObject(); // end of data object json.writeEndObject(); json.close(); // output to stream this.jsonMetrics.add(jsonString.getBuffer().toString()); } } catch (Exception ex) { log.error("Error adding metrics to queue", ex); } }
private void recurseSupportedProperties( JsonGenerator jgen, String currentVocab, Class<?> beanType, ActionDescriptor actionDescriptor, ActionInputParameter actionInputParameter, Object currentCallValue) throws IntrospectionException, IOException { // TODO support Option provider by other method args? final BeanInfo beanInfo = Introspector.getBeanInfo(beanType); final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); // TODO collection and map for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { final Method writeMethod = propertyDescriptor.getWriteMethod(); if (writeMethod == null) { continue; } final Class<?> propertyType = propertyDescriptor.getPropertyType(); // TODO: the property name must be a valid URI - need to check context for terms? String propertyName = getWritableExposedPropertyOrPropertyName(propertyDescriptor); if (DataType.isSingleValueType(propertyType)) { final Property property = new Property( beanType, propertyDescriptor.getReadMethod(), propertyDescriptor.getWriteMethod(), propertyDescriptor.getName()); Object propertyValue = PropertyUtils.getPropertyValue(currentCallValue, propertyDescriptor); MethodParameter methodParameter = new MethodParameter(propertyDescriptor.getWriteMethod(), 0); ActionInputParameter propertySetterInputParameter = new ActionInputParameter(methodParameter, propertyValue); final Object[] possiblePropertyValues = actionInputParameter.getPossibleValues( propertyDescriptor.getWriteMethod(), 0, actionDescriptor); writeSupportedProperty( jgen, currentVocab, propertySetterInputParameter, propertyName, property, possiblePropertyValues); } else { jgen.writeStartObject(); jgen.writeStringField("hydra:property", propertyName); // TODO: is the property required -> for bean props we need the Access annotation to express // that jgen.writeObjectFieldStart( getPropertyOrClassNameInVocab( currentVocab, "rangeIncludes", LdContextFactory.HTTP_SCHEMA_ORG, "schema:")); Expose expose = AnnotationUtils.getAnnotation(propertyType, Expose.class); String subClass; if (expose != null) { subClass = expose.value(); } else { subClass = propertyType.getSimpleName(); } jgen.writeStringField( getPropertyOrClassNameInVocab( currentVocab, "subClassOf", "http://www.w3.org/2000/01/rdf-schema#", "rdfs:"), subClass); jgen.writeArrayFieldStart("hydra:supportedProperty"); Object propertyValue = PropertyUtils.getPropertyValue(currentCallValue, propertyDescriptor); recurseSupportedProperties( jgen, currentVocab, propertyType, actionDescriptor, actionInputParameter, propertyValue); jgen.writeEndArray(); jgen.writeEndObject(); jgen.writeEndObject(); } } }
@Override public void serialize(List<Link> links, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException { try { Collection<Link> simpleLinks = new ArrayList<Link>(); Collection<Affordance> affordances = new ArrayList<Affordance>(); Collection<Link> templatedLinks = new ArrayList<Link>(); Collection<Affordance> templatedAffordances = new ArrayList<Affordance>(); Collection<Affordance> collectionAffordances = new ArrayList<Affordance>(); Link selfRel = null; for (Link link : links) { if (link instanceof Affordance) { final Affordance affordance = (Affordance) link; final List<ActionDescriptor> actionDescriptors = affordance.getActionDescriptors(); if (!actionDescriptors.isEmpty()) { if (affordance.isTemplated()) { templatedAffordances.add(affordance); } else { if (!affordance.isSelfRel() && Cardinality.COLLECTION == affordance.getCardinality()) { collectionAffordances.add(affordance); } else { affordances.add(affordance); } } } else { if (affordance.isTemplated()) { templatedLinks.add(affordance); } else { simpleLinks.add(affordance); } } } else if (link.isTemplated()) { templatedLinks.add(link); } else { simpleLinks.add(link); } if ("self".equals(link.getRel())) { selfRel = link; } } for (Affordance templatedAffordance : templatedAffordances) { jgen.writeObjectFieldStart(templatedAffordance.getRel()); jgen.writeStringField("@type", "hydra:IriTemplate"); jgen.writeStringField("hydra:template", templatedAffordance.getHref()); final List<ActionDescriptor> actionDescriptors = templatedAffordance.getActionDescriptors(); ActionDescriptor actionDescriptor = actionDescriptors.get(0); jgen.writeArrayFieldStart("hydra:mapping"); writeHydraVariableMapping(jgen, actionDescriptor, actionDescriptor.getPathVariableNames()); writeHydraVariableMapping(jgen, actionDescriptor, actionDescriptor.getRequestParamNames()); jgen.writeEndArray(); jgen.writeEndObject(); } for (Link templatedLink : templatedLinks) { // we only have the template, no access to method params jgen.writeObjectFieldStart(templatedLink.getRel()); jgen.writeStringField("@type", "hydra:IriTemplate"); jgen.writeStringField("hydra:template", templatedLink.getHref()); jgen.writeArrayFieldStart("hydra:mapping"); writeHydraVariableMapping(jgen, null, templatedLink.getVariableNames()); jgen.writeEndArray(); jgen.writeEndObject(); } @SuppressWarnings("unchecked") Deque<LdContext> contextStack = (Deque<LdContext>) serializerProvider.getAttribute(JacksonHydraSerializer.KEY_LD_CONTEXT); String currentVocab = (contextStack != null && !contextStack.isEmpty()) ? contextStack.peek().vocab : null; // related collections if (!collectionAffordances.isEmpty()) { jgen.writeArrayFieldStart("hydra:collection"); for (Affordance collectionAffordance : collectionAffordances) { jgen.writeStartObject(); jgen.writeStringField(JsonLdKeywords.AT_TYPE, "hydra:Collection"); jgen.writeStringField(JsonLdKeywords.AT_ID, collectionAffordance.getHref()); jgen.writeObjectFieldStart("hydra:manages"); jgen.writeStringField("hydra:property", collectionAffordance.getRel()); // a) in the case of </Alice> :knows /bob the subject must be /Alice // b) in the case of <> orderedItem /latte-1 the subject is an anonymous resource of type // Order // c) in the case of </order/1> :seller </store> the object must be the store // 1. where is the information *about* the subject or object: the type or @id // 2. how to decide if the collection manages items for a subject or object? // ad 1.) // ad a) self rel of the Resource that has the collection affordance: looking through link // list // at serialization time is possible // ad b) a candidate is the class given as value of @ExposesResourceFor on the controller // that defines the method which leads us to believe we have a collection: // either a GET /orders handler having a collection return type or the POST /orders. // Works only if the GET or POST has no request mapping path of its own // an alternative is to use {} without type if @ExposesResourceFor is not present // ad c) like a // ad 2.) // we know the affordance is a collection // * we could pass information into build(rel), like // .rel().reverseRel("schema:seller").build() // * we could use build("myReversedTerm") and look at the @context to see if it is // reversed, // if so, we know that the manages block must use object not subject. However weird if // the // reverse term is never really used in the json-ld // * we could have a registry which says if a property is meant to be reversed in a // certain context // and use that to find out if we need subject or object, like :seller -> if (selfRel != null) { // prefer rev over rel, assuming that rev exists to be used by RDF serialization if (collectionAffordance.getRev() != null) { jgen.writeStringField("hydra:object", selfRel.getHref()); } else if (collectionAffordance.getRel() != null) { jgen.writeStringField("hydra:subject", selfRel.getHref()); } } else { // prefer rev over rel, assuming that rev exists to be used by RDF serialization if (collectionAffordance.getRev() != null) { jgen.writeObjectFieldStart("hydra:object"); jgen.writeEndObject(); } else if (collectionAffordance.getRel() != null) { jgen.writeObjectFieldStart("hydra:subject"); jgen.writeEndObject(); } } jgen.writeEndObject(); // end manages List<ActionDescriptor> actionDescriptors = collectionAffordance.getActionDescriptors(); if (!actionDescriptors.isEmpty()) { jgen.writeArrayFieldStart("hydra:operation"); } writeActionDescriptors(jgen, currentVocab, actionDescriptors); if (!actionDescriptors.isEmpty()) { jgen.writeEndArray(); // end hydra:operation } jgen.writeEndObject(); // end collection } jgen.writeEndArray(); } for (Affordance affordance : affordances) { final String rel = affordance.getRel(); List<ActionDescriptor> actionDescriptors = affordance.getActionDescriptors(); if (!actionDescriptors.isEmpty()) { if (!Link.REL_SELF.equals(rel)) { jgen.writeObjectFieldStart(rel); // begin rel } jgen.writeStringField(JsonLdKeywords.AT_ID, affordance.getHref()); jgen.writeArrayFieldStart("hydra:operation"); } writeActionDescriptors(jgen, currentVocab, actionDescriptors); if (!actionDescriptors.isEmpty()) { jgen.writeEndArray(); // end hydra:operation if (!Link.REL_SELF.equals(rel)) { jgen.writeEndObject(); // end rel } } } for (Link simpleLink : simpleLinks) { final String rel = simpleLink.getRel(); if (Link.REL_SELF.equals(rel)) { jgen.writeStringField("@id", simpleLink.getHref()); } else { String linkAttributeName = IanaRels.isIanaRel(rel) ? IANA_REL_PREFIX + rel : rel; jgen.writeObjectFieldStart(linkAttributeName); jgen.writeStringField("@id", simpleLink.getHref()); jgen.writeEndObject(); } } } catch (IntrospectionException e) { throw new RuntimeException(e); } }