/*
 * 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.eagle.log.entity.test;

import org.apache.eagle.log.entity.meta.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import org.apache.eagle.log.base.taggedlog.TaggedLogAPIEntity;

@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@Table("unittest")
@ColumnFamily("f")
@Prefix("testTSEntity")
@Service("TestTimeSeriesAPIEntity")
@TimeSeries(true)
@Tags({
       "cluster", "datacenter", "random"
    })
public class TestTimeSeriesAPIEntity extends TaggedLogAPIEntity {

    @Column("a")
    private int field1;
    @Column("b")
    private Integer field2;
    @Column("c")
    private long field3;
    @Column("d")
    private Long field4;
    @Column("e")
    private double field5;
    @Column("f")
    private Double field6;
    @Column("g")
    private String field7;

    public int getField1() {
        return field1;
    }

    public void setField1(int field1) {
        this.field1 = field1;
        pcs.firePropertyChange("field1", null, null);
    }

    public Integer getField2() {
        return field2;
    }

    public void setField2(Integer field2) {
        this.field2 = field2;
        pcs.firePropertyChange("field2", null, null);
    }

    public long getField3() {
        return field3;
    }

    public void setField3(long field3) {
        this.field3 = field3;
        pcs.firePropertyChange("field3", null, null);
    }

    public Long getField4() {
        return field4;
    }

    public void setField4(Long field4) {
        this.field4 = field4;
        pcs.firePropertyChange("field4", null, null);
    }

    public double getField5() {
        return field5;
    }

    public void setField5(double field5) {
        this.field5 = field5;
        pcs.firePropertyChange("field5", null, null);
    }

    public Double getField6() {
        return field6;
    }

    public void setField6(Double field6) {
        this.field6 = field6;
        pcs.firePropertyChange("field6", null, null);
    }

    public String getField7() {
        return field7;
    }

    public void setField7(String field7) {
        this.field7 = field7;
        pcs.firePropertyChange("field7", null, null);
    }
}
