/* * Copyright to the original author or authors. * * 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 org.rioproject.deploy; import net.jini.id.Uuid; import org.rioproject.costmodel.ResourceCost; import org.rioproject.opstring.ServiceElement; import java.io.Serializable; import java.util.*; /** * A <tt>ServiceRecord</tt> documents service instantiated time, discard time, * where the service ran and contains * {@link org.rioproject.costmodel.ResourceCost} information for * system resources accessed during the service's execution. * * @author Dennis Reedy */ public class ServiceRecord implements Comparable, Serializable { @SuppressWarnings("unused") static final long serialVersionUID = 1L; /** * Indicates a service which is currently active, */ public static final int ACTIVE_SERVICE_RECORD = 1; /** * Specifies a service which has been discarded, is not longer active */ public static final int INACTIVE_SERVICE_RECORD = 1 << 1; /** * The uuid for the service */ private Uuid uuid; /** * The hostname of the compute resource the service is * running on */ private String hostName; /** * The Date the service was instantiated */ private Date instantiated; /** * The most recent Date the ServiceRecord was updated */ private Date updated; /** * The Date the service was discarded */ private Date discarded; /** * The ServiceElement for the service */ private ServiceElement sElem; /** * The type of this record, ACTIVE_SERVICE_RECORD or INACTIVE_SERVICE_RECORD */ private int type; /** * If the service is forked, and active, the corresponding pid of the exec'd service */ private int pid=-1; /** * ResourceCost instances for the service */ private final List<ResourceCost> resourceCosts = new ArrayList<ResourceCost>(); /** * Create a ServiceRecord. The <code>type</code> property is set to * <code>ACTIVE_SERVICE_RECORD</code>, and the <code>instantiated</code> * property set to the current Date * * @param uuid Unique ID of the service * @param sElem The ServiceElement * @param hostName The hostname of the compute resource the service is * running on */ public ServiceRecord(Uuid uuid, ServiceElement sElem, String hostName) { this(uuid, sElem, hostName, ACTIVE_SERVICE_RECORD, new Date()); } /** * Create a ServiceRecord. The <code>type</code> property is set to * <code>ACTIVE_SERVICE_RECORD</code>, and the <code>instantiated</code> * property set to the current Date * * @param uuid Unique ID of the service * @param sElem The ServiceElement * @param hostName The hostname of the compute resource the service is * running on * @param type The type of the record * @param instantiated The Date the service has been instantiated */ public ServiceRecord(Uuid uuid, ServiceElement sElem, String hostName, int type, Date instantiated) { if(uuid == null) throw new IllegalArgumentException("uuid is null"); if(sElem == null) throw new IllegalArgumentException("sElem is null"); if(hostName == null) throw new IllegalArgumentException("hostName is null"); doSetType(type); this.uuid = uuid; this.sElem = sElem; this.hostName = hostName; this.instantiated = new Date(instantiated.getTime()); } /** * Get the uuid for the service * * @return The unique ID for the service */ public Uuid getServiceID() { return (uuid); } /** * @return The service name */ public String getName() { return (sElem.getName()); } /** * @return The hostName */ public String getHostName() { return(hostName); } /** * Set the type of this record to be either * <code>ACTIVE_SERVICE_RECORD</code> or * <code>INACTIVE_SERVICE_RECORD</code><br> * * @param type The type of the ServiceRecord * @throws IllegalArgumentException if the supplied type is neither * <code>ACTIVE_SERVICE_RECORD</code> or * <code>INACTIVE_SERVICE_RECORD</code> */ public void setType(int type) { doSetType(type); } private void doSetType(int type) { if(type == 0 || type != (type & (ACTIVE_SERVICE_RECORD | INACTIVE_SERVICE_RECORD))) throw new IllegalArgumentException("bad type"); this.type = type; } /** * Get the type of ServiceRecord <br> * * @return <code>ACTIVE_SERVICE_RECORD</code> or * <code>INACTIVE_SERVICE_RECORD</code> */ public int getType() { return (type); } /** * @return The <code>Date</code> the service was instantiated */ public Date getInstantiationDate() { Date d = null; if(instantiated != null) d = new Date(instantiated.getTime()); return (d); } /** * Set that the ServiceRecord has been updated */ public void setUpdated() { this.updated = new Date(); } /** * @return The Date that the ServiceRecord was been updated */ public Date getUpdated() { Date d = null; if(updated != null) d = new Date(updated.getTime()); return (d); } /** * @param discarded The <code>Date</code> the service was discarded */ public void setDiscardedDate(Date discarded) { if(discarded!=null) this.discarded = new Date(discarded.getTime()); } /** * @return The <code>Date</code> the service was discarded. If the * service has not been discarded then this method will return * <code>null</code> */ public Date getDiscardedDate() { Date d = null; if(discarded!=null) d = new Date(discarded.getTime()); return (d); } /** * @return The ServiceElement object */ public ServiceElement getServiceElement() { return (sElem); } /** * Compute the elapsed time the service has been active. If the service * is still active the value returned will be based on the current time * * @return The elapsed time (in milliseconds) the service has been instantiated */ public long computeElapsedTime() { long t0 = instantiated.getTime(); long t1 = System.currentTimeMillis(); if(discarded != null && ((type & ServiceRecord.INACTIVE_SERVICE_RECORD) != 0)) { t1 = discarded.getTime(); } return (t1 - t0); } /** * Add a ResourceCost * * @param resourceCost The ResourceCost to add. If the ResourceCost for * a named resource already exists, it will be replaced */ public void addResourceCost(ResourceCost resourceCost) { if(resourceCost == null) throw new IllegalArgumentException("resourceCost is null"); synchronized(resourceCosts) { ResourceCost[] rCosts = resourceCosts.toArray(new ResourceCost[resourceCosts.size()]); boolean updated = false; for(ResourceCost rCost : rCosts) { if(rCost.getResourceName().equals(resourceCost.getResourceName())) { int ndx = resourceCosts.indexOf(rCost); resourceCosts.set(ndx, resourceCost); updated = true; break; } } if(!updated) resourceCosts.add(resourceCost); } } /** * Get the ResourceCost instances. * * @return An array of ResourceCost instances. A new array * will be allocated each time. If there are no ResourceCost instances, an * empty array will be returned. */ public ResourceCost[] getResourceCosts() { ResourceCost[] rCosts; synchronized(resourceCosts) { rCosts = resourceCosts.toArray(new ResourceCost[resourceCosts.size()]); } return (rCosts); } /** * Compares this ServiceRecord to another ServiceRecord with respect to the * ServiceRecord instantiation Date. * * @param o The Object to be compared. * @return A negative integer if this ServiceRecord has an instantiatedDate * before the ServiceRecord being compared to, zero if the instantiatedDate * property is equal, or a positive number if the instantiatedDate is later. */ public int compareTo(Object o) { ServiceRecord serviceRecord = (ServiceRecord)o; return (instantiated.compareTo(serviceRecord.getInstantiationDate())); } public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } /** * A ServiceRecord is equal to another ServiceRecord if their Uuid's * and instantiation Dates are equal */ public boolean equals(Object o) { if(this == o) return (true); if(!(o instanceof ServiceRecord)) return (false); ServiceRecord that = (ServiceRecord)o; return (this.uuid.equals(that.uuid) && this.instantiated.equals(that.instantiated)); } /** * Override hashCode to return the hashCode of the Uuid and the * instantiated Date */ public int hashCode() { int hc = 17; hc = 37*hc+uuid.hashCode(); hc = 37*hc+instantiated.hashCode(); return (hc); } public String toString() { return "ServiceRecord {" + "hostName='" + hostName + '\'' + ", instantiated=" + instantiated + ", updated=" + updated + ", discarded=" + discarded + ", service=" + sElem.getName() + ", resourceCosts=" + resourceCosts + ", type=" + type + '}'; } }