org.apache.flume.channel.file.FlumeEvent Maven / Gradle / Ivy
/*
* 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.channel.file;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.util.HashMap;
import java.util.Map;
import org.apache.flume.Event;
/**
* Persistable wrapper for Event
*/
class FlumeEvent implements Event, Writable {
private static final byte EVENT_MAP_TEXT_WRITABLE_ID = Byte.valueOf(Integer.valueOf(-116).byteValue());
private static ThreadLocal ENCODER_FACTORY =
new ThreadLocal() {
@Override
protected CharsetEncoder initialValue() {
return Charset.forName("UTF-8").newEncoder().
onMalformedInput(CodingErrorAction.REPLACE).
onUnmappableCharacter(CodingErrorAction.REPLACE);
}
};
private static ThreadLocal DECODER_FACTORY =
new ThreadLocal() {
@Override
protected CharsetDecoder initialValue() {
return Charset.forName("UTF-8").newDecoder().
onMalformedInput(CodingErrorAction.REPLACE).
onUnmappableCharacter(CodingErrorAction.REPLACE);
}
};
private Map headers;
private byte[] body;
private FlumeEvent() {
this(null, null);
}
FlumeEvent(Map headers, byte[] body) {
this.headers = headers;
this.body = body;
}
@Override
public Map getHeaders() {
return headers;
}
@Override
public void setHeaders(Map headers) {
this.headers = headers;
}
@Override
public byte[] getBody() {
return body;
}
@Override
public void setBody(byte[] body) {
this.body = body;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeByte(0);
Map writeHeaders = getHeaders();
if (null != writeHeaders) {
out.writeInt(headers.size());
CharsetEncoder encoder = ENCODER_FACTORY.get();
for (String key : headers.keySet()) {
out.writeByte(EVENT_MAP_TEXT_WRITABLE_ID);
ByteBuffer keyBytes = encoder.encode(CharBuffer.wrap(key.toCharArray()));
int keyLength = keyBytes.limit();
WritableUtils.writeVInt(out, keyLength);
out.write(keyBytes.array(), 0, keyLength);
String value = headers.get(key);
out.write(EVENT_MAP_TEXT_WRITABLE_ID);
ByteBuffer valueBytes = encoder.encode(CharBuffer.wrap(value.toCharArray()));
int valueLength = valueBytes.limit();
WritableUtils.writeVInt(out, valueLength );
out.write(valueBytes.array(), 0, valueLength);
}
}
else {
out.writeInt( 0 );
}
byte[] body = getBody();
if(body == null) {
out.writeInt(-1);
} else {
out.writeInt(body.length);
out.write(body);
}
}
@Override
public void readFields(DataInput in) throws IOException {
// newClasses from AbstractMapWritable in Hadoop Common
byte newClasses = in.readByte();
// skip over newClasses since only Text is used
for (byte i = 0; i < newClasses; i++) {
in.readByte();
in.readUTF();
}
Map newHeaders = new HashMap();
int numEntries = in.readInt();
CharsetDecoder decoder = DECODER_FACTORY.get();
for (int i = 0; i < numEntries; i++) {
byte keyClassId = in.readByte();
assert (keyClassId == EVENT_MAP_TEXT_WRITABLE_ID);
int keyLength = WritableUtils.readVInt(in);
byte[] keyBytes = new byte[ keyLength ];
in.readFully( keyBytes, 0, keyLength );
String key = decoder.decode( ByteBuffer.wrap(keyBytes) ).toString();
byte valueClassId = in.readByte();
assert (valueClassId == EVENT_MAP_TEXT_WRITABLE_ID);
int valueLength = WritableUtils.readVInt(in);
byte[] valueBytes = new byte[ valueLength ];
in.readFully(valueBytes, 0, valueLength);
String value = decoder.decode(ByteBuffer.wrap(valueBytes)).toString();
newHeaders.put(key, value);
}
setHeaders(newHeaders);
byte[] body = null;
int bodyLength = in.readInt();
if(bodyLength != -1) {
body = new byte[bodyLength];
in.readFully(body);
}
setBody(body);
}
static FlumeEvent from(DataInput in) throws IOException {
FlumeEvent event = new FlumeEvent();
event.readFields(in);
return event;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy