com.hurence.logisland.record.StandardRecord.java Source code

Java tutorial

Introduction

Here is the source code for com.hurence.logisland.record.StandardRecord.java

Source

/**
 * Copyright (C) 2016 Hurence (support@hurence.com)
 *
 * Licensed 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.
 */
/*
 Copyright 2016 Hurence
    
 Licensed 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 com.hurence.logisland.record;

import com.hurence.logisland.logging.ComponentLog;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * Encapsulation of an Event a map of Fields
 *
 * @author Tom Bailet
 */
public class StandardRecord implements Record {

    private static Logger logger = LoggerFactory.getLogger(StandardRecord.class);

    public static String DEFAULT_RECORD_TYPE = "generic";

    private Map<String, Field> fields = new HashMap<>();

    private List<String> errors = new ArrayList<>();

    public StandardRecord() {
        this(DEFAULT_RECORD_TYPE);
    }

    public StandardRecord(String type) {
        this.setType(type);
        this.setTime(new Date());
        this.setId(UUID.randomUUID().toString());
    }

    public StandardRecord(Record toClone) {
        this();
        this.setType(toClone.getType());
        this.setTime(toClone.getTime());
        this.setId(UUID.randomUUID().toString());
        toClone.getAllFieldsSorted().forEach(this::setField);
        this.errors = (List<String>) toClone.getErrors();
    }

    @Override
    public String toString() {
        return "Record{" + "fields=" + fields + ", time=" + getTime() + ", type='" + getType() + '\'' + ", id='"
                + getId() + '\'' + '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        StandardRecord record = (StandardRecord) o;

        if (getAllFields() == null || record.getAllFields() == null
                || !CollectionUtils.isEqualCollection(this.getAllFields(), record.getAllFields()))

            return false;
        return getId() != null ? getId().equals(record.getId()) : record.getId() == null;

    }

    @Override
    public int hashCode() {
        int result = fields != null ? fields.hashCode() : 0;
        result = 31 * result + (getId() != null ? getId().hashCode() : 0);
        return result;
    }

    @Override
    public Position getPosition() {
        if (hasPosition())
            return (Position) getField(FieldDictionary.RECORD_POSITION).asRecord();
        else
            return null;
    }

    @Override
    public Record setPosition(Position position) {
        if (position != null)
            setField(FieldDictionary.RECORD_POSITION, FieldType.RECORD, position);
        return this;
    }

    @Override
    public boolean hasPosition() {
        return hasField(FieldDictionary.RECORD_POSITION);
    }

    @Override
    public Date getTime() {
        try {
            return new Date((long) getField(FieldDictionary.RECORD_TIME).getRawValue());
        } catch (Exception ex) {
            return null;
        }
    }

    @Override
    public Record setTime(Date recordTime) {
        if (recordTime != null)
            setField(FieldDictionary.RECORD_TIME, FieldType.LONG, recordTime.getTime());
        return this;
    }

    @Override
    public Record setTime(long timestamp) {
        setField(FieldDictionary.RECORD_TIME, FieldType.LONG, timestamp);
        return this;
    }

    @Override
    public Record setFields(Map<String, Field> fields) {
        this.fields = fields;
        return this;
    }

    @Override
    public Record addFields(Map<String, Field> fields) {
        fields.values().forEach(this::setField);
        return this;
    }

    @Override
    public Record setType(String type) {
        if (type != null) {
            this.setField(FieldDictionary.RECORD_TYPE, FieldType.STRING, type);
        }
        return this;
    }

    /**
     * get the
     *
     * @return
     */
    @Override
    public String getType() {
        return getField(FieldDictionary.RECORD_TYPE).asString();
    }

    /**
     * retrieve record id
     *
     * @return the record id
     */
    @Override
    public String getId() {
        return getField(FieldDictionary.RECORD_ID).asString();
    }

    /**
     * sets Record id
     *
     * @param id
     */
    public Record setId(String id) {
        setField(FieldDictionary.RECORD_ID, FieldType.STRING, id);
        return this;
    }

    /**
     * checks if a field is defined
     *
     * @param fieldName
     * @return
     */
    @Override
    public boolean hasField(String fieldName) {
        return fields.containsKey(fieldName);
    }

    /**
     * set a field value
     *
     * @param field
     */
    @Override
    public Record setField(Field field) {
        fields.put(field.getName(), field);
        return this;
    }

    /**
     * set a field value
     *
     * @param fieldName
     * @param value
     */
    @Override
    public Record setField(String fieldName, FieldType fieldType, Object value) {
        setField(new Field(fieldName, fieldType, value));
        return this;
    }

    /**
     * set a field value as a String value
     *
     * @param fieldName the name of the string field
     * @param value     the value to be added
     */
    @Override
    public Record setStringField(String fieldName, String value) {
        setField(new Field(fieldName, FieldType.STRING, value));
        return this;
    }

    /**
     * remove a field by its name
     *
     * @param fieldName
     */
    @Override
    public Field removeField(String fieldName) {
        if (fieldName.equals(FieldDictionary.RECORD_TIME)) {
            logger.debug("trying to remove record_time field. we won't let you do that !!");
            return fields.get(FieldDictionary.RECORD_TIME);
        } else {
            return fields.remove(fieldName);
        }
    }

    /**
     * retrieve a field by its name
     *
     * @param fieldName
     */
    @Override
    public Field getField(String fieldName) {
        return fields.get(fieldName);
    }

    @Override
    public Record setStringFields(Map<String, String> entrySets) {
        Objects.requireNonNull(entrySets, "Argument can not be null");
        for (Map.Entry<String, String> entry : entrySets.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            this.setStringField(key, value);
        }
        return this;
    }

    @Override
    public Collection<Field> getAllFieldsSorted() {
        List<Field> fields = new ArrayList<>(getAllFields());
        Collections.sort(fields, (left, right) -> left.getName().compareTo(right.getName()));
        return fields;
    }

    @Override
    public Collection<Field> getAllFields() {
        return fields.values();
    }

    @Override
    public Set<String> getAllFieldNames() {
        return fields.keySet();
    }

    @Override
    public Set<Map.Entry<String, Field>> getFieldsEntrySet() {
        return fields.entrySet();
    }

    /**
     * checks if record has no fields other than id, time and type
     *
     * @return true if fields is emty
     */
    @Override
    public boolean isEmpty() {
        return fields.size() == 3;
    }

    @Override
    public boolean isValid() {

        for (final Field field : getAllFields()) {
            boolean isValid = true;
            try {

                if (field.isSet()) {
                    switch (field.getType()) {
                    case STRING:
                        isValid = field.getRawValue() instanceof String;
                        break;
                    case INT:
                        isValid = field.getRawValue() instanceof Integer;
                        break;
                    case LONG:
                        isValid = field.getRawValue() instanceof Long;
                        break;
                    case FLOAT:
                        isValid = field.getRawValue() instanceof Float;
                        break;
                    case DOUBLE:
                        isValid = field.getRawValue() instanceof Double;
                        break;
                    case BOOLEAN:
                        isValid = field.getRawValue() instanceof Boolean;
                        break;
                    case ARRAY:
                        isValid = field.getRawValue() instanceof Collection;
                        break;
                    case RECORD:
                        isValid = field.getRawValue() instanceof Record;
                        break;
                    case MAP:
                        isValid = field.getRawValue() instanceof Map;
                        break;
                    case NULL:
                        isValid = field.getRawValue() == null;
                        break;
                    case BYTES:
                        isValid = field.getRawValue() instanceof byte[] || field.getRawValue() instanceof Byte[];
                        break;

                    default:
                        isValid = false;
                        break;
                    }
                }
            } catch (Throwable ex) {
                return false;
            }
            if (!isValid) {
                logger.info("field {} is not an instance of type {}", field.getName(), field.getType());
                return false;
            }
        }
        return true;

    }

    /**
     * The number of fields (minus the 3 technical ones)
     *
     * @return number of real fields
     */
    @Override
    public int size() {
        return fields.size() - 3;
    }

    /**
     * compute roughly the size in bytes for an event
     * id, type and creationDate are ignored
     *
     * @return
     */
    @Override
    public int sizeInBytes() {

        int size = 0;

        for (Map.Entry<String, Field> entry : getFieldsEntrySet()) {

            Field field = entry.getValue();
            Object fieldValue = field.getRawValue();
            FieldType fieldType = field.getType();

            // dump event field as record attribute

            try {
                switch (fieldType) {
                case STRING:
                    size += ((String) fieldValue).getBytes().length;
                    break;
                case INT:
                    size += 4;
                    break;
                case LONG:
                    size += 8;
                    break;
                case FLOAT:
                    size += 4;
                    break;
                case DOUBLE:
                    size += 8;
                    break;
                case BOOLEAN:
                    size += 1;
                    break;
                default:
                    break;
                }
            } catch (Exception ex) {
                // nothing to do
            }

        }

        return size;
    }

    @Override
    public Record addError(final String type, final String message) {
        StringBuilder finalMessage = new StringBuilder();
        finalMessage.append(type);
        if (message == null || !message.isEmpty()) {
            finalMessage.append(": ");
            finalMessage.append(message);
        }
        errors.add(finalMessage.toString());
        setField(FieldDictionary.RECORD_ERRORS, FieldType.ARRAY, errors);
        return this;
    }

    @Override
    public Record addError(String errorType) {
        return addError(errorType, null);
    }

    @Override
    public Record addError(String errorType, ComponentLog logger, String errorMessage) {
        logger.error(errorMessage);
        return addError(errorType, errorMessage);
    }

    @Override
    public Record addError(String errorType, ComponentLog logger, String errorMessage, Object[] os) {
        logger.error(errorMessage, os);
        return addError(errorType, errorMessage);
    }

    @Override
    public Collection<String> getErrors() {
        return new ArrayList<>(errors);
    }
}