All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.flume.source.http.JSONHandler Maven / Gradle / Ivy

There is a newer version: 4.15.0-HBase-1.5
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.flume.source.http;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import java.io.BufferedReader;
import java.lang.reflect.Type;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.event.EventBuilder;
import org.apache.flume.event.JSONEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * JSONHandler for HTTPSource that accepts an array of events.
 *
 * This handler throws exception if the deserialization fails because of bad
 * format or any other reason.
 *
 *
 * Each event must be encoded as a map with two key-value pairs. 

1. headers * - the key for this key-value pair is "headers". The value for this key is * another map, which represent the event headers. These headers are inserted * into the Flume event as is.

2. body - The body is a string which * represents the body of the event. The key for this key-value pair is "body". * All key-value pairs are considered to be headers. An example:

[{"headers" * : {"a":"b", "c":"d"},"body": "random_body"}, {"headers" : {"e": "f"},"body": * "random_body2"}]

would be interpreted as the following two flume events: *

* Event with body: "random_body" (in UTF-8/UTF-16/UTF-32 encoded bytes) * and headers : (a:b, c:d)

* * Event with body: "random_body2" (in UTF-8/UTF-16/UTF-32 encoded bytes) and * headers : (e:f)

* * The charset of the body is read from the request and used. If no charset is * set in the request, then the charset is assumed to be JSON's default - UTF-8. * The JSON handler supports UTF-8, UTF-16 and UTF-32. * * To set the charset, the request must have content type specified as * "application/json; charset=UTF-8" (replace UTF-8 with UTF-16 or UTF-32 as * required). * * One way to create an event in the format expected by this handler, is to * use {@linkplain JSONEvent} and use {@linkplain Gson} to create the JSON * string using the * {@linkplain Gson#toJson(java.lang.Object, java.lang.reflect.Type) } * method. The type token to pass as the 2nd argument of this method * for list of events can be created by:

* * Type type = new TypeToken>() {}.getType();

* */ public class JSONHandler implements HTTPSourceHandler { private static final Logger LOG = LoggerFactory.getLogger(JSONHandler.class); private final Type listType = new TypeToken>() { }.getType(); private final Gson gson; public JSONHandler() { gson = new GsonBuilder().disableHtmlEscaping().create(); } /** * {@inheritDoc} */ @Override public List getEvents(HttpServletRequest request) throws Exception { BufferedReader reader = request.getReader(); String charset = request.getCharacterEncoding(); //UTF-8 is default for JSON. If no charset is specified, UTF-8 is to //be assumed. if (charset == null) { LOG.debug("Charset is null, default charset of UTF-8 will be used."); charset = "UTF-8"; } else if (!(charset.equalsIgnoreCase("utf-8") || charset.equalsIgnoreCase("utf-16") || charset.equalsIgnoreCase("utf-32"))) { LOG.error("Unsupported character set in request {}. " + "JSON handler supports UTF-8, " + "UTF-16 and UTF-32 only.", charset); throw new UnsupportedCharsetException("JSON handler supports UTF-8, " + "UTF-16 and UTF-32 only."); } /* * Gson throws Exception if the data is not parseable to JSON. * Need not catch it since the source will catch it and return error. */ List eventList = new ArrayList(0); try { eventList = gson.fromJson(reader, listType); } catch (JsonSyntaxException ex) { throw new HTTPBadRequestException("Request has invalid JSON Syntax.", ex); } for (Event e : eventList) { ((JSONEvent) e).setCharset(charset); } return getSimpleEvents(eventList); } @Override public void configure(Context context) { } private List getSimpleEvents(List events) { List newEvents = new ArrayList(events.size()); for(Event e:events) { newEvents.add(EventBuilder.withBody(e.getBody(), e.getHeaders())); } return newEvents; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy