/* * RHQ Management Platform * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.core.domain.resource; import java.io.Serializable; import java.util.Date; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToOne; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import javax.persistence.SequenceGenerator; import javax.persistence.Table; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.content.InstalledPackage; /** * Describes one request to create a new resource. * * @author Jason Dobies */ @Entity(name = "CreateResourceHistory") @NamedQueries({ @NamedQuery(name = CreateResourceHistory.QUERY_FIND_WITH_STATUS, query = "SELECT crh FROM CreateResourceHistory AS crh WHERE crh.status = :status"), @NamedQuery(name = CreateResourceHistory.QUERY_FIND_BY_PARENT_RESOURCE_ID, query = "" // + "SELECT crh " // + " FROM CreateResourceHistory AS crh " // + " WHERE crh.parentResource.id = :id" // + " AND ( crh.ctime > :startTime OR :startTime IS NULL ) " // + " AND ( crh.mtime < :endTime OR :endTime IS NULL ) "), @NamedQuery(name = CreateResourceHistory.QUERY_FIND_BY_ID, query = "SELECT crh FROM CreateResourceHistory AS crh WHERE crh.id = :id"), @NamedQuery(name = CreateResourceHistory.QUERY_DELETE_BY_RESOURCES, query = "DELETE FROM CreateResourceHistory crh WHERE crh.parentResource.id IN ( :resourceIds ) )"), @NamedQuery(name = CreateResourceHistory.QUERY_FIND_BY_CHILD_RESOURCE_KEY, query = "" // + "SELECT crh " // + " FROM CreateResourceHistory AS crh " // + " WHERE crh.parentResource.id = :parentResourceId " // + " AND crh.newResourceKey = :newResourceKey ") }) @SequenceGenerator(allocationSize = org.rhq.core.domain.util.Constants.ALLOCATION_SIZE, name = "RHQ_CREATE_RES_HIST_ID_SEQ", sequenceName = "RHQ_CREATE_RES_HIST_ID_SEQ") @Table(name = "RHQ_CREATE_RES_HIST") public class CreateResourceHistory implements Serializable { // Constants -------------------------------------------- private static final long serialVersionUID = 1L; public static final String QUERY_FIND_WITH_STATUS = "CreateResourceHistory.findWithStatus"; public static final String QUERY_FIND_BY_PARENT_RESOURCE_ID = "CreateResourceHistory.findByParentResourceId"; public static final String QUERY_FIND_BY_ID = "CreateResourceHistory.findById"; public static final String QUERY_DELETE_BY_RESOURCES = "CreateResourceHistory.deleteByResources"; public static final String QUERY_FIND_BY_CHILD_RESOURCE_KEY = "CreateResourceHistory.findByChildResourceKey"; // Attributes -------------------------------------------- @GeneratedValue(generator = "RHQ_CREATE_RES_HIST_ID_SEQ", strategy = GenerationType.AUTO) @Id private int id; @Column(name = "ERROR_MESSAGE") private String errorMessage; @Column(name = "SUBJECT_NAME", nullable = false) private String subjectName; @Column(name = "CTIME", nullable = false) private long ctime = System.currentTimeMillis(); @Column(name = "MTIME", nullable = false) private long mtime = System.currentTimeMillis(); /** * Links to the parent under which this resource is created. There will always be a parent; resources created at the * highest level (i.e. "servers") will have the platform resource as their parent. */ @JoinColumn(name = "PARENT_RESOURCE_ID", referencedColumnName = "ID", nullable = false) @ManyToOne private Resource parentResource; /** * Resource instance created on the server onto which to hang these create requests. */ @Column(name = "CREATED_RESOURCE_NAME", nullable = true) private String createdResourceName; /** * Resource key assigned to the newly created resource by the plugin if this request is successful. */ @Column(name = "NEW_RESOURCE_KEY") private String newResourceKey; /** * Status of this create request. */ @Column(name = "STATUS", nullable = false) @Enumerated(EnumType.STRING) private CreateResourceStatus status; /** * Type of resource being created. */ @JoinColumn(name = "RESOURCE_TYPE_ID", referencedColumnName = "ID") @OneToOne(fetch = FetchType.EAGER) private ResourceType resourceType; /** * For configuration-backed resource creation, this instance carries the values entered by the user for the newly * created resource. For content-backed resource creation, this instance carries any configuration values about the * content itself that may be specified when the content is created. */ @JoinColumn(name = "CONFIGURATION_ID", referencedColumnName = "ID") @OneToOne(cascade = CascadeType.ALL) private Configuration configuration; /** * For content backed resource creation, this indicates the type of content being created as part of this request. */ @JoinColumn(name = "INSTALLED_PACKAGE_ID", referencedColumnName = "ID", nullable = true) @OneToOne(cascade = CascadeType.PERSIST, optional = true) private InstalledPackage installedPackage; // Constructors -------------------------------------------- /** * Creates an empty instance. */ public CreateResourceHistory() { } /** * Helper constructor when creating a request for a configuration-backed resource. * * @param parentResource resource under which the new resource is created * @param resourceType type of resource being created * @param subjectName user creating the resource * @param resourceConfiguration the intial configuration for the resource being created */ public CreateResourceHistory(Resource parentResource, ResourceType resourceType, String subjectName, Configuration resourceConfiguration) { this.parentResource = parentResource; this.subjectName = subjectName; this.resourceType = resourceType; this.configuration = resourceConfiguration; } /** * Helper constructor when creating a request for a content-backed resource. * * @param parentResource resource under which the new resource is created * @param resourceType type of resource being created * @param subjectName user creating the resource * @param installedPackage the package being created */ public CreateResourceHistory(Resource parentResource, ResourceType resourceType, String subjectName, InstalledPackage installedPackage) { this.parentResource = parentResource; this.subjectName = subjectName; this.resourceType = resourceType; this.installedPackage = installedPackage; } // Public -------------------------------------------- public int getId() { return id; } public void setId(int id) { this.id = id; } public Resource getParentResource() { return parentResource; } public void setParentResource(Resource parentResource) { this.parentResource = parentResource; } public String getCreatedResourceName() { return createdResourceName; } public void setCreatedResourceName(String createdResourceName) { this.createdResourceName = createdResourceName; } public String getNewResourceKey() { return newResourceKey; } public void setNewResourceKey(String newResourceKey) { this.newResourceKey = newResourceKey; } public CreateResourceStatus getStatus() { return status; } public void setStatus(CreateResourceStatus status) { this.status = status; } public String getErrorMessage() { return errorMessage; } /** * Calling this method with a non-<code>null</code> error message implies that the request's status is * {@link CreateResourceStatus#FAILURE}. The inverse is <i>not</i> true - that is, if you set the error message to * <code>null</code>, the status is left as-is; it will not assume that a <code>null</code> error message means the * status is successful. * * @param errorMessage description of the error */ public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; if (errorMessage != null) { setStatus(CreateResourceStatus.FAILURE); } } public String getSubjectName() { return subjectName; } public void setSubjectName(String subjectName) { this.subjectName = subjectName; } public long getCreatedTime() { return ctime; } public Date getCreatedDate() { return new Date(ctime); } public long getLastModifiedTime() { return mtime; } public Date getLastModifiedDate() { return new Date(mtime); } public ResourceType getResourceType() { return resourceType; } public void setResourceType(ResourceType resourceType) { this.resourceType = resourceType; } public Configuration getConfiguration() { return configuration; } public void setConfiguration(Configuration configuration) { this.configuration = configuration; } public InstalledPackage getInstalledPackage() { return installedPackage; } public void setInstalledPackage(InstalledPackage installedPackage) { this.installedPackage = installedPackage; } /** * The duration of the configuration update request which simply is the difference between the * {@link #getCreatedTime()} and the {@link #getLastModifiedTime()}. If the request hasn't completed yet, this will * be the difference between the current time and the created time. * * @return the duration of time that the request took or is taking to complete */ public long getDuration() { long start = this.ctime; long end = this.mtime; if ((status == null) || (status == CreateResourceStatus.IN_PROGRESS)) { end = System.currentTimeMillis(); } return end - start; } // Package -------------------------------------------- @PrePersist void onPersist() { this.mtime = System.currentTimeMillis(); } @PreUpdate void onUpdate() { this.mtime = System.currentTimeMillis(); } // Object Overridden -------------------------------------------- @Override public int hashCode() { final int PRIME = 31; int result = 1; result = (PRIME * result) + (int) (ctime ^ (ctime >>> 32)); result = (PRIME * result) + ((subjectName == null) ? 0 : subjectName.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if ((obj == null) || !(obj instanceof CreateResourceHistory)) { return false; } final CreateResourceHistory other = (CreateResourceHistory) obj; if (ctime != other.ctime) { return false; } if (subjectName == null) { if (other.subjectName != null) { return false; } } else if (!subjectName.equals(other.subjectName)) { return false; } return true; } }