use of com.fasterxml.jackson.databind.type.TypeFactory in project druid by druid-io.
the class DirectDruidClient method run.
@Override
public Sequence<T> run(final Query<T> query, final Map<String, Object> context) {
QueryToolChest<T, Query<T>> toolChest = warehouse.getToolChest(query);
boolean isBySegment = BaseQuery.getContextBySegment(query, false);
Pair<JavaType, JavaType> types = typesMap.get(query.getClass());
if (types == null) {
final TypeFactory typeFactory = objectMapper.getTypeFactory();
JavaType baseType = typeFactory.constructType(toolChest.getResultTypeReference());
JavaType bySegmentType = typeFactory.constructParametricType(Result.class, typeFactory.constructParametricType(BySegmentResultValueClass.class, baseType));
types = Pair.of(baseType, bySegmentType);
typesMap.put(query.getClass(), types);
}
final JavaType typeRef;
if (isBySegment) {
typeRef = types.rhs;
} else {
typeRef = types.lhs;
}
final ListenableFuture<InputStream> future;
final String url = String.format("http://%s/druid/v2/", host);
final String cancelUrl = String.format("http://%s/druid/v2/%s", host, query.getId());
try {
log.debug("Querying queryId[%s] url[%s]", query.getId(), url);
final long requestStartTime = System.currentTimeMillis();
final ServiceMetricEvent.Builder builder = toolChest.makeMetricBuilder(query);
builder.setDimension("server", host);
final HttpResponseHandler<InputStream, InputStream> responseHandler = new HttpResponseHandler<InputStream, InputStream>() {
private long responseStartTime;
private final AtomicLong byteCount = new AtomicLong(0);
private final BlockingQueue<InputStream> queue = new LinkedBlockingQueue<>();
private final AtomicBoolean done = new AtomicBoolean(false);
@Override
public ClientResponse<InputStream> handleResponse(HttpResponse response) {
log.debug("Initial response from url[%s] for queryId[%s]", url, query.getId());
responseStartTime = System.currentTimeMillis();
emitter.emit(builder.build("query/node/ttfb", responseStartTime - requestStartTime));
try {
final String responseContext = response.headers().get("X-Druid-Response-Context");
// context may be null in case of error or query timeout
if (responseContext != null) {
context.putAll(objectMapper.<Map<String, Object>>readValue(responseContext, new TypeReference<Map<String, Object>>() {
}));
}
queue.put(new ChannelBufferInputStream(response.getContent()));
} catch (final IOException e) {
log.error(e, "Error parsing response context from url [%s]", url);
return ClientResponse.<InputStream>finished(new InputStream() {
@Override
public int read() throws IOException {
throw e;
}
});
} catch (InterruptedException e) {
log.error(e, "Queue appending interrupted");
Thread.currentThread().interrupt();
throw Throwables.propagate(e);
}
byteCount.addAndGet(response.getContent().readableBytes());
return ClientResponse.<InputStream>finished(new SequenceInputStream(new Enumeration<InputStream>() {
@Override
public boolean hasMoreElements() {
// Then the stream should be spouting good InputStreams.
synchronized (done) {
return !done.get() || !queue.isEmpty();
}
}
@Override
public InputStream nextElement() {
try {
return queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw Throwables.propagate(e);
}
}
}));
}
@Override
public ClientResponse<InputStream> handleChunk(ClientResponse<InputStream> clientResponse, HttpChunk chunk) {
final ChannelBuffer channelBuffer = chunk.getContent();
final int bytes = channelBuffer.readableBytes();
if (bytes > 0) {
try {
queue.put(new ChannelBufferInputStream(channelBuffer));
} catch (InterruptedException e) {
log.error(e, "Unable to put finalizing input stream into Sequence queue for url [%s]", url);
Thread.currentThread().interrupt();
throw Throwables.propagate(e);
}
byteCount.addAndGet(bytes);
}
return clientResponse;
}
@Override
public ClientResponse<InputStream> done(ClientResponse<InputStream> clientResponse) {
long stopTime = System.currentTimeMillis();
log.debug("Completed queryId[%s] request to url[%s] with %,d bytes returned in %,d millis [%,f b/s].", query.getId(), url, byteCount.get(), stopTime - responseStartTime, byteCount.get() / (0.0001 * (stopTime - responseStartTime)));
emitter.emit(builder.build("query/node/time", stopTime - requestStartTime));
emitter.emit(builder.build("query/node/bytes", byteCount.get()));
synchronized (done) {
try {
// An empty byte array is put at the end to give the SequenceInputStream.close() as something to close out
// after done is set to true, regardless of the rest of the stream's state.
queue.put(ByteSource.empty().openStream());
} catch (InterruptedException e) {
log.error(e, "Unable to put finalizing input stream into Sequence queue for url [%s]", url);
Thread.currentThread().interrupt();
throw Throwables.propagate(e);
} catch (IOException e) {
// This should never happen
throw Throwables.propagate(e);
} finally {
done.set(true);
}
}
return ClientResponse.<InputStream>finished(clientResponse.getObj());
}
@Override
public void exceptionCaught(final ClientResponse<InputStream> clientResponse, final Throwable e) {
// Don't wait for lock in case the lock had something to do with the error
synchronized (done) {
done.set(true);
// Make a best effort to put a zero length buffer into the queue in case something is waiting on the take()
// If nothing is waiting on take(), this will be closed out anyways.
queue.offer(new InputStream() {
@Override
public int read() throws IOException {
throw new IOException(e);
}
});
}
}
};
future = httpClient.go(new Request(HttpMethod.POST, new URL(url)).setContent(objectMapper.writeValueAsBytes(query)).setHeader(HttpHeaders.Names.CONTENT_TYPE, isSmile ? SmileMediaTypes.APPLICATION_JACKSON_SMILE : MediaType.APPLICATION_JSON), responseHandler);
queryWatcher.registerQuery(query, future);
openConnections.getAndIncrement();
Futures.addCallback(future, new FutureCallback<InputStream>() {
@Override
public void onSuccess(InputStream result) {
openConnections.getAndDecrement();
}
@Override
public void onFailure(Throwable t) {
openConnections.getAndDecrement();
if (future.isCancelled()) {
// forward the cancellation to underlying queriable node
try {
StatusResponseHolder res = httpClient.go(new Request(HttpMethod.DELETE, new URL(cancelUrl)).setContent(objectMapper.writeValueAsBytes(query)).setHeader(HttpHeaders.Names.CONTENT_TYPE, isSmile ? SmileMediaTypes.APPLICATION_JACKSON_SMILE : MediaType.APPLICATION_JSON), new StatusResponseHandler(Charsets.UTF_8)).get();
if (res.getStatus().getCode() >= 500) {
throw new RE("Error cancelling query[%s]: queriable node returned status[%d] [%s].", res.getStatus().getCode(), res.getStatus().getReasonPhrase());
}
} catch (IOException | ExecutionException | InterruptedException e) {
Throwables.propagate(e);
}
}
}
});
} catch (IOException e) {
throw Throwables.propagate(e);
}
Sequence<T> retVal = new BaseSequence<>(new BaseSequence.IteratorMaker<T, JsonParserIterator<T>>() {
@Override
public JsonParserIterator<T> make() {
return new JsonParserIterator<T>(typeRef, future, url);
}
@Override
public void cleanup(JsonParserIterator<T> iterFromMake) {
CloseQuietly.close(iterFromMake);
}
});
// avoid the cost of de-serializing and then re-serializing again when adding to cache
if (!isBySegment) {
retVal = Sequences.map(retVal, toolChest.makePreComputeManipulatorFn(query, MetricManipulatorFns.deserializing()));
}
return retVal;
}
use of com.fasterxml.jackson.databind.type.TypeFactory in project jackson-databind by FasterXML.
the class ObjectArraySerializer method acceptJsonFormatVisitor.
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException {
JsonArrayFormatVisitor arrayVisitor = visitor.expectArrayFormat(typeHint);
if (arrayVisitor != null) {
TypeFactory tf = visitor.getProvider().getTypeFactory();
JavaType contentType = tf.moreSpecificType(_elementType, typeHint.getContentType());
if (contentType == null) {
visitor.getProvider().reportBadDefinition(_elementType, "Could not resolve type: " + _elementType);
}
JsonSerializer<?> valueSer = _elementSerializer;
if (valueSer == null) {
valueSer = visitor.getProvider().findValueSerializer(contentType, _property);
}
arrayVisitor.itemsFormat(valueSer, contentType);
}
}
use of com.fasterxml.jackson.databind.type.TypeFactory in project jackson-databind by FasterXML.
the class ClassNameIdResolver method _typeFromId.
protected JavaType _typeFromId(String id, DatabindContext ctxt) throws IOException {
/* 30-Jan-2010, tatu: Most ids are basic class names; so let's first
* check if any generics info is added; and only then ask factory
* to do translation when necessary
*/
TypeFactory tf = ctxt.getTypeFactory();
if (id.indexOf('<') > 0) {
// note: may want to try combining with specialization (esp for EnumMap)?
return tf.constructFromCanonical(id);
}
Class<?> cls;
try {
cls = tf.findClass(id);
} catch (ClassNotFoundException e) {
// DeserializationContext, just playing it safe
if (ctxt instanceof DeserializationContext) {
DeserializationContext dctxt = (DeserializationContext) ctxt;
// First: we may have problem handlers that can deal with it?
return dctxt.handleUnknownTypeId(_baseType, id, this, "no such class found");
}
// ... meaning that we really should never get here.
return null;
} catch (Exception e) {
throw new IllegalArgumentException("Invalid type id '" + id + "' (for id type 'Id.class'): " + e.getMessage(), e);
}
return tf.constructSpecializedType(_baseType, cls);
}
use of com.fasterxml.jackson.databind.type.TypeFactory in project jackson-databind by FasterXML.
the class TestJacksonTypes method testJavaType.
public void testJavaType() throws Exception {
ObjectMapper mapper = new ObjectMapper();
TypeFactory tf = TypeFactory.defaultInstance();
// first simple type:
String json = mapper.writeValueAsString(tf.constructType(String.class));
assertEquals(quote(java.lang.String.class.getName()), json);
// and back
JavaType t = mapper.readValue(json, JavaType.class);
assertNotNull(t);
assertEquals(String.class, t.getRawClass());
}
use of com.fasterxml.jackson.databind.type.TypeFactory in project winery by eclipse.
the class JAXBHelper method addTemplatesToTopology.
/**
* This method adds a selection of {@link TNodeTemplate}- and {@link TRelationshipTemplate}-XML-Strings to a {@link
* TTopologyTemplate}-XML-String using JAXB. After the templates have been added, the {@link TTopologyTemplate}
* object is re-marshalled to an XML-String.
* <p>
* This method is called by the selectionHandler.jsp after several Node or RelationshipTemplates have been chosen in
* a dialog.
*
* @param topology the topology as XML string
* @param allTemplateChoicesAsXML all possible template choices as TOSCA-XML strings containing the
* complete templates
* @param selectedNodeTemplatesAsJSON the names of the selected NodeTemplates as JSONArray
* @param selectedRelationshipTemplatesAsJSON the names of the selected RelationshipTemplates as JSONArray
* @return the complete topology XML string
*/
public static String addTemplatesToTopology(String topology, String allTemplateChoicesAsXML, String selectedNodeTemplatesAsJSON, String selectedRelationshipTemplatesAsJSON) {
try {
// initialization code for the jackson types used to convert JSON string arrays to a java.util.List
ObjectMapper mapper = new ObjectMapper();
TypeFactory factory = mapper.getTypeFactory();
// convert the JSON array containing the names of the selected RelationshipTemplates to a java.util.List
List<String> selectedRelationshipTemplates = mapper.readValue(selectedRelationshipTemplatesAsJSON, factory.constructCollectionType(List.class, String.class));
// convert the topology and the choices to objects using JAXB
TTopologyTemplate topologyTemplate = getTopologyAsJaxBObject(topology);
List<TEntityTemplate> allTemplateChoices = getEntityTemplatesAsJaxBObject(allTemplateChoicesAsXML);
// this distinction of cases is necessary because it is possible that only RelationshipTemplates have been selected
if (selectedNodeTemplatesAsJSON != null) {
// convert the JSON string array containing the names of the selected NodeTemplates to a java.util.List
List<String> selectedNodeTemplates = mapper.readValue(selectedNodeTemplatesAsJSON, factory.constructCollectionType(List.class, String.class));
// search the selected NodeTemplate in the List of all choices by its name to receive its object which will ne added to the topology
for (String nodeTemplateName : selectedNodeTemplates) {
for (TEntityTemplate choice : allTemplateChoices) {
if (choice instanceof TNodeTemplate) {
TNodeTemplate nodeTemplate = (TNodeTemplate) choice;
// however similar names are not possible at this location due to the implementation of the selection dialogs
if (nodeTemplateName.equals(nodeTemplate.getName())) {
// add the selected NodeTemplate to the topology
topologyTemplate.getNodeTemplateOrRelationshipTemplate().add(nodeTemplate);
// Re-add it to avoid errors.
for (TEntityTemplate entity : topologyTemplate.getNodeTemplateOrRelationshipTemplate()) {
if (entity instanceof TRelationshipTemplate) {
TRelationshipTemplate relationshipTemplate = (TRelationshipTemplate) entity;
if (relationshipTemplate.getSourceElement().getRef() == null) {
// connect to the added NodeTemplate
TRelationshipTemplate.SourceOrTargetElement sourceElement = new TRelationshipTemplate.SourceOrTargetElement();
sourceElement.setRef(nodeTemplate);
relationshipTemplate.setSourceElement(sourceElement);
}
}
}
}
}
}
}
// now search and add the selected RelationshipTemplate object connecting to the inserted NodeTemplate
for (String relationshipTemplateName : selectedRelationshipTemplates) {
for (TEntityTemplate toBeAdded : allTemplateChoices) {
if (toBeAdded instanceof TRelationshipTemplate) {
TRelationshipTemplate relationshipTemplate = (TRelationshipTemplate) toBeAdded;
if (relationshipTemplateName.equals(relationshipTemplate.getName())) {
topologyTemplate.getNodeTemplateOrRelationshipTemplate().add(relationshipTemplate);
}
}
}
}
} else {
// in this case only Relationship Templates have been selected
List<TRelationshipTemplate> allRelationshipTemplateChoices = JAXBHelper.getRelationshipTemplatesAsJaxBObject(allTemplateChoicesAsXML);
// add the target Node Template to the topology which is unique due to the implementation of the selection dialog
topologyTemplate.getNodeTemplateOrRelationshipTemplate().add((TNodeTemplate) ((TRelationshipTemplate) allRelationshipTemplateChoices.get(0)).getTargetElement().getRef());
// search the JAXB object of the selected RelationshipTemplate and add it to the topology
for (String relationshipTemplateName : selectedRelationshipTemplates) {
for (TRelationshipTemplate choice : allRelationshipTemplateChoices) {
if (relationshipTemplateName.equals(choice.getName())) {
topologyTemplate.getNodeTemplateOrRelationshipTemplate().add(choice);
}
}
}
for (TEntityTemplate entityTemplate : topologyTemplate.getNodeTemplateOrRelationshipTemplate()) {
if (entityTemplate instanceof TRelationshipTemplate) {
TRelationshipTemplate relationship = (TRelationshipTemplate) entityTemplate;
// Re-add it to avoid errors.
if (relationship.getSourceElement().getRef() == null) {
relationship.getSourceElement().setRef((TNodeTemplate) ((TRelationshipTemplate) allRelationshipTemplateChoices.get(0)).getTargetElement().getRef());
}
}
}
}
// re-convert the topology from a JAXB object to an XML string and return it
Definitions definitions = new Definitions();
TServiceTemplate st = new TServiceTemplate();
st.setTopologyTemplate(topologyTemplate);
definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().add(st);
JAXBContext context = JAXBContext.newInstance(Definitions.class);
Marshaller m = context.createMarshaller();
StringWriter stringWriter = new StringWriter();
m.marshal(definitions, stringWriter);
return stringWriter.toString();
} catch (JAXBException | IOException e) {
logger.error(e.getLocalizedMessage());
}
return null;
}
Aggregations