View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  
22  package org.opencastproject.serviceregistry.api;
23  
24  import org.opencastproject.util.NotFoundException;
25  
26  import java.util.Collection;
27  import java.util.LinkedHashMap;
28  import java.util.Map;
29  
30  import javax.xml.bind.annotation.XmlAccessType;
31  import javax.xml.bind.annotation.XmlAccessorType;
32  import javax.xml.bind.annotation.XmlAttribute;
33  import javax.xml.bind.annotation.XmlElement;
34  import javax.xml.bind.annotation.XmlElementWrapper;
35  import javax.xml.bind.annotation.XmlRootElement;
36  import javax.xml.bind.annotation.XmlType;
37  
38  /**
39   * Mappings between the registered hosts and their load factors.
40   */
41  @XmlType(name = "load", namespace = "http://serviceregistry.opencastproject.org")
42  @XmlRootElement(name = "load", namespace = "http://serviceregistry.opencastproject.org")
43  @XmlAccessorType(XmlAccessType.NONE)
44  public class SystemLoad {
45  
46    /** No-arg constructor needed by JAXB */
47    public SystemLoad() {
48      nodeLoads = new LinkedHashMap<String, NodeLoad>();
49    }
50  
51    /** The list of nodes and their current load */
52    protected Map<String, NodeLoad> nodeLoads;
53  
54    /**
55     * Get the list of nodes and their current loadfactor.
56     *
57     * @return the nodeLoads
58     */
59    @XmlElementWrapper(name = "nodes")
60    @XmlElement(name = "node")
61    public Collection<NodeLoad> getNodeLoads() {
62      return nodeLoads.values();
63    }
64  
65    /**
66     * Sets the list of nodes and their current loadfactor.
67     *
68     * @param newLoads
69     *          the nodeLoads to set
70     */
71    public void setNodeLoads(Collection<NodeLoad> newLoads) {
72      for (NodeLoad node : newLoads) {
73        nodeLoads.put(node.getHost(), node);
74      }
75    }
76  
77    /**
78     * Updates the load factor for a node
79     * @param host
80     *   The host to update
81     * @param modifier
82     *   The modifier to apply to the load
83     */
84    public void updateNodeLoad(String host, float modifier) throws NotFoundException {
85      if (!nodeLoads.containsKey(host)) {
86        throw new NotFoundException("Host " + host + " not in this load object");
87      }
88      nodeLoads.get(host).modifyLoad(modifier);
89    }
90  
91    /**
92     * Adds a node to the map of load values, overwriting an existing entry if the node is already present in the map
93     * @param load
94     *          the nodeLoad to add
95     */
96    public void addNodeLoad(NodeLoad load) {
97      nodeLoads.put(load.getHost(), load);
98    }
99  
100   /**
101    * Gets a specific host from the map, if present.  If the node is not present, or the host value is null, this method returns null.
102    * @param host
103    *        The hostname of the host you are interested in.
104    * @return
105    *        The specific host from the map, if present.  If the node is not present, or the host value is null, this method returns null.
106    */
107   public NodeLoad get(String host) {
108     if (host != null && this.containsHost(host))
109       return nodeLoads.get(host);
110     return null;
111   }
112 
113   /**
114    * Returns true if the load map contains the host in question.
115    * @param host
116    *          The hostname of the host you are interested in.
117    * @return
118    *          True if the host is present, false if the host is not, or the host variable is null.
119    */
120   public boolean containsHost(String host) {
121     if (host != null)
122       return nodeLoads.containsKey(host);
123     return false;
124   }
125 
126   @Override
127   public String toString() {
128     StringBuilder sb = new StringBuilder();
129     sb.append("Current Loads:\n");
130     for (NodeLoad n : getNodeLoads()) {
131       sb.append(String.format("  %s: %f / %f\n", n.getHost(), n.getCurrentLoad(), n.getMaxLoad()));
132     }
133     return sb.toString();
134   }
135 
136 
137   /** A record of a node in the cluster and its load factor */
138   @XmlType(name = "nodetype", namespace = "http://serviceregistry.opencastproject.org")
139   @XmlRootElement(name = "nodetype", namespace = "http://serviceregistry.opencastproject.org")
140   @XmlAccessorType(XmlAccessType.NONE)
141   public static class NodeLoad implements Comparable<NodeLoad> {
142 
143     /** No-arg constructor needed by JAXB */
144     public NodeLoad() {
145     }
146 
147     public NodeLoad(String host, float currentload, float maxload) {
148       this.host = host;
149       this.currentLoad = currentload;
150       this.maxLoad = maxload;
151     }
152 
153     /** This node's base URL */
154     @XmlAttribute
155     protected String host;
156 
157     /** This node's current load */
158     @XmlAttribute
159     protected float currentLoad;
160 
161     @XmlAttribute
162     protected float maxLoad;
163 
164     /**
165      * @return the host
166      */
167     public String getHost() {
168       return host;
169     }
170 
171     /**
172      * @param host
173      *          the host to set
174      */
175     public void setHost(String host) {
176       this.host = host;
177     }
178 
179     /**
180      * @return the load factor, current / maxload
181      */
182     public float getLoadFactor() {
183       return currentLoad / maxLoad;
184     }
185 
186     /**
187      * Modifies the load for this node
188      * @param modifier
189      *              the amount to add or subtract from the current load
190      */
191     public void modifyLoad(float modifier) {
192       this.currentLoad = this.currentLoad + modifier;
193     }
194 
195     public float getCurrentLoad() {
196       return currentLoad;
197     }
198 
199     public void setCurrentLoad(float load) {
200       this.currentLoad = load;
201     }
202 
203     public float getMaxLoad() {
204       return maxLoad;
205     }
206 
207     public void setMaxLoad(float load) {
208       this.maxLoad = load;
209     }
210 
211 
212     @Override
213     public int compareTo(NodeLoad other) {
214       if (other.getLoadFactor() > this.getLoadFactor()) {
215         return 1;
216       } else if (this.getLoadFactor() > other.getLoadFactor()) {
217         return -1;
218       } else {
219         return 0;
220       }
221     }
222 
223     public boolean exceeds(NodeLoad other) {
224       if (this.compareTo(other) > 1) {
225         return true;
226       }
227       return false;
228     }
229   }
230 }