/*
 * 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);
	}
}
