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

com.yhzdys.myosotis.serialize.AvroSerializer Maven / Gradle / Ivy

There is a newer version: 1.3.4
Show newest version
package com.yhzdys.myosotis.serialize;

import com.yhzdys.myosotis.entity.MyosotisConfig;
import com.yhzdys.myosotis.entity.MyosotisEvent;
import com.yhzdys.myosotis.entity.PollingData;
import com.yhzdys.myosotis.enums.EventType;
import com.yhzdys.myosotis.exception.MyosotisException;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericArray;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.BinaryEncoder;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.util.Utf8;
import org.apache.commons.lang3.ArrayUtils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public final class AvroSerializer implements Serializer {

    private final Schema polling_list_schema;
    private final Schema polling_schema;
    private final DatumWriter> polling_list_writer;
    private final DatumReader> polling_list_reader;

    private final Schema events_schema;
    private final Schema event_schema;
    private final DatumWriter> events_writer;
    private final DatumReader> events_reader;

    private final Schema configs_schema;
    private final Schema config_schema;
    private final DatumWriter> configs_writer;
    private final DatumReader> configs_reader;

    private final String k_id = "id";
    private final String k_namespace = "namespace";
    private final String k_config_key = "configKey";
    private final String k_config_value = "configValue";
    private final String k_version = "version";
    private final String k_type = "type";
    private final String k_is_all = "isAll";
    private final String k_data = "data";

    public AvroSerializer() {
        try {
            Schema.Parser parser = new Schema.Parser();

            this.polling_list_schema = parser.parse(loadAvsc("schema/polling_data.avsc"));
            this.polling_schema = this.polling_list_schema.getElementType();
            this.polling_list_writer = new GenericDatumWriter<>(this.polling_list_schema);
            this.polling_list_reader = new GenericDatumReader<>(this.polling_list_schema);

            this.events_schema = parser.parse(loadAvsc("schema/events.avsc"));
            this.event_schema = this.events_schema.getElementType();
            this.events_writer = new GenericDatumWriter<>(this.events_schema);
            this.events_reader = new GenericDatumReader<>(this.events_schema);

            this.configs_schema = parser.parse(loadAvsc("schema/configs.avsc"));
            this.config_schema = this.configs_schema.getElementType();
            this.configs_writer = new GenericDatumWriter<>(this.configs_schema);
            this.configs_reader = new GenericDatumReader<>(this.configs_schema);
        } catch (Throwable e) {
            throw new MyosotisException("Initialize schemas failed.", e);
        }
    }

    private InputStream loadAvsc(String schemaPath) throws Throwable {
        URL url = AvroSerializer.class.getClassLoader().getResource(schemaPath);
        if (url == null) {
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            if (classLoader != null) {
                url = classLoader.getResource(schemaPath);
            }
        }
        if (url == null) {
            url = ClassLoader.getSystemClassLoader().getResource(schemaPath);
        }
        if (url == null) {
            throw new MyosotisException("Can not load avsc file: " + schemaPath);
        }
        return url.openStream();
    }

    @Override
    public byte[] serializePollingData(List list) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(out, null);

        GenericArray recordArray = new GenericData.Array<>(list.size(), polling_list_schema);
        for (PollingData pollingData : list) {
            GenericRecord record = new GenericData.Record(polling_schema);
            record.put(k_is_all, pollingData.isAll());
            record.put(k_namespace, pollingData.getNamespace());
            record.put(k_data, pollingData.getData());
            recordArray.add(record);
        }

        polling_list_writer.write(recordArray, encoder);
        encoder.flush();
        out.close();
        return out.toByteArray();
    }

    @Override
    @SuppressWarnings("unchecked")
    public List deserializePollingData(byte[] data) throws Exception {
        Decoder decoder = DecoderFactory.get().binaryDecoder(data, null);
        GenericArray recordArray = polling_list_reader.read(null, decoder);

        List list = new ArrayList<>();
        for (GenericRecord record : recordArray) {
            PollingData pollingData = new PollingData();
            pollingData.setAll((boolean) record.get(k_is_all));
            pollingData.setNamespace(record.get(k_namespace).toString());
            Map dataTempMap = (Map) record.get(k_data);
            Map dataMap = new HashMap<>(dataTempMap.size());
            for (Map.Entry entry : dataTempMap.entrySet()) {
                dataMap.put(entry.getKey().toString(), entry.getValue());
            }
            pollingData.setData(dataMap);
            list.add(pollingData);
        }
        return list;
    }

    @Override
    public byte[] serializeEvents(List list) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(outputStream, null);

        GenericArray recordArray = new GenericData.Array<>(list.size(), events_schema);
        for (MyosotisEvent event : list) {
            GenericRecord record = new GenericData.Record(event_schema);
            recordArray.add(record);

            record.put(k_id, event.getId());
            record.put(k_namespace, event.getNamespace());
            record.put(k_config_key, event.getConfigKey());
            record.put(k_type, event.getType().toString());
            // 删除模式下,无需传递下面的字段
            if (EventType.DELETE.equals(event.getType())) {
                continue;
            }
            record.put(k_config_value, event.getConfigValue());
            record.put(k_version, event.getVersion());
        }

        events_writer.write(recordArray, encoder);
        encoder.flush();
        outputStream.close();
        return outputStream.toByteArray();
    }

    @Override
    public List deserializeEvents(byte[] data) throws Exception {
        if (ArrayUtils.isEmpty(data)) {
            return Collections.emptyList();
        }
        Decoder decoder = DecoderFactory.get().binaryDecoder(data, null);
        GenericArray recordArray = events_reader.read(null, decoder);

        List eventList = new ArrayList<>();
        for (GenericRecord record : recordArray) {
            Object id = record.get(k_id);
            Object namespace = record.get(k_namespace);
            Object configKey = record.get(k_config_key);
            Object configValue = record.get(k_config_value);
            Object version = record.get(k_version);
            Object type = record.get(k_type);
            eventList.add(
                    new MyosotisEvent()
                            .setId(id == null ? null : (Long) id)
                            .setNamespace(namespace == null ? null : namespace.toString())
                            .setConfigKey(configKey == null ? null : configKey.toString())
                            .setConfigValue(configValue == null ? null : configValue.toString())
                            .setVersion(version == null ? 0 : (Integer) version)
                            .setType(EventType.valueOf(type.toString()))
            );
        }
        return eventList;
    }

    @Override
    public byte[] serializeConfigs(List list) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(outputStream, null);

        GenericArray recordArray = new GenericData.Array<>(list.size(), configs_schema);
        for (MyosotisConfig config : list) {
            GenericRecord record = new GenericData.Record(config_schema);
            record.put(k_id, config.getId());
            record.put(k_namespace, config.getNamespace());
            record.put(k_config_key, config.getConfigKey());
            record.put(k_config_value, config.getConfigValue());
            record.put(k_version, config.getVersion());
            recordArray.add(record);
        }

        configs_writer.write(recordArray, encoder);
        encoder.flush();
        outputStream.close();
        return outputStream.toByteArray();
    }

    @Override
    public List deserializeConfigs(byte[] data) throws Exception {
        if (ArrayUtils.isEmpty(data)) {
            return Collections.emptyList();
        }
        Decoder decoder = DecoderFactory.get().binaryDecoder(data, null);
        GenericArray recordArray = configs_reader.read(null, decoder);

        List configList = new ArrayList<>();
        for (GenericRecord record : recordArray) {
            Object id = record.get(k_id);
            Object namespace = record.get(k_namespace).toString();
            String configKey = record.get(k_config_key).toString();
            Object configValue = record.get(k_config_value);
            Object version = record.get(k_version);
            configList.add(
                    new MyosotisConfig()
                            .setId(id == null ? null : (Long) id)
                            .setNamespace(namespace.toString())
                            .setConfigKey(configKey)
                            .setConfigValue(configValue == null ? null : configValue.toString())
                            .setVersion(version == null ? 0 : (Integer) version)
            );
        }
        return configList;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy