// 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 com.cloud.secstorage;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import com.cloud.utils.DateUtil;
import org.apache.cloudstack.api.InternalIdentity;

@Entity
@Table(name="cmd_exec_log")
public class CommandExecLogVO implements InternalIdentity {
	
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
	private long id;
    
    @Column(name="host_id")
	private long hostId;
    
    @Column(name="instance_id")
	private long instanceId;
	
    @Column(name="command_name")
	private String commandName;
    
    @Column(name="weight")
    private int weight;
	
    @Column(name="created")
    @Temporal(value=TemporalType.TIMESTAMP)
    private Date created;
    
    public CommandExecLogVO() {
    }
    
    public CommandExecLogVO(long hostId, long instanceId, String commandName, int weight) {
    	this.hostId = hostId;
    	this.instanceId = instanceId;
    	this.commandName = commandName;
    	this.weight = weight;
    	this.created = DateUtil.currentGMTTime();
    }
    
    public long getId() {
    	return this.id;
    }
    
    public long getHostId() {
    	return this.hostId;
    }
    
    public void setHostId(long hostId) {
    	this.hostId = hostId;
    }
    
    public long getInstanceId() {
    	return this.instanceId;
    }
    
    public void setInstanceId(long instanceId) {
    	this.instanceId = instanceId;
    }
    
    public String getCommandName() {
    	return this.commandName;
    }
    
    public void setCommandName(String commandName) {
    	this.commandName = commandName;
    }
    
    public int getWeight() {
    	return weight;
    }
    
    public void setWeight(int weight) {
    	this.weight = weight;
    }
    
    public Date getCreated() {
    	return this.created;
    }
    
    public void setCreated(Date created) {
    	this.created = created;
    }
}
