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.impl.jpa;
23  
24  import org.opencastproject.serviceregistry.api.ServiceRegistration;
25  import org.opencastproject.serviceregistry.api.ServiceState;
26  
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  
30  import java.util.Date;
31  
32  import javax.persistence.Access;
33  import javax.persistence.AccessType;
34  import javax.persistence.Column;
35  import javax.persistence.Entity;
36  import javax.persistence.GeneratedValue;
37  import javax.persistence.Id;
38  import javax.persistence.Index;
39  import javax.persistence.JoinColumn;
40  import javax.persistence.ManyToOne;
41  import javax.persistence.NamedQueries;
42  import javax.persistence.NamedQuery;
43  import javax.persistence.PostLoad;
44  import javax.persistence.Table;
45  import javax.persistence.Temporal;
46  import javax.persistence.TemporalType;
47  import javax.persistence.Transient;
48  import javax.persistence.UniqueConstraint;
49  
50  /**
51   * A record of a service that creates and manages receipts.
52   */
53  @Entity(name = "ServiceRegistration")
54  @Access(AccessType.FIELD)
55  @Table(
56      name = "oc_service_registration",
57      indexes = {
58          @Index(name = "IX_oc_service_registration_service_type", columnList = ("service_type")),
59          @Index(name = "IX_oc_service_registration_service_state", columnList = ("service_state")),
60          @Index(name = "IX_oc_service_registration_active", columnList = ("active")),
61          @Index(name = "IX_oc_service_registration_host_registration", columnList = ("host_registration")),
62      },
63      uniqueConstraints = @UniqueConstraint(
64          name = "UNQ_oc_service_registration",
65          columnNames = { "host_registration", "service_type" }
66      )
67  )
68  @NamedQueries({
69      @NamedQuery(
70          name = "ServiceRegistration.statistics",
71          query = "SELECT job.processorServiceRegistrationFK as serviceRegistration, job.status, "
72              + "count(job.status) as numJobs, "
73              + "avg(job.queueTime) as meanQueue, "
74              + "avg(job.runTime) as meanRun FROM Job job "
75              + "where job.dateCreated >= :minDateCreated and job.dateCreated <= :maxDateCreated "
76              + "group by job.processorServiceRegistrationFK, job.status"
77      ),
78      @NamedQuery(
79          name = "ServiceRegistration.hostloads",
80          query = "SELECT job.processorServiceRegistration.hostRegistration.baseUrl as host, "
81              + "job.status, sum(job.jobLoad), job.processorServiceRegistration.hostRegistration.maxLoad "
82              + "FROM Job job "
83              + "WHERE job.processorServiceRegistration.online=true "
84              + "and job.processorServiceRegistration.active=true "
85              + "and job.processorServiceRegistration.hostRegistration.maintenanceMode=false "
86              + "AND job.status in :statuses "
87              + "AND job.creatorServiceRegistration.serviceType != :workflow_type "
88              + "GROUP BY job.processorServiceRegistration.hostRegistration.baseUrl, "
89              + "job.status, job.processorServiceRegistration.hostRegistration.maxLoad"
90      ),
91      @NamedQuery(
92          name = "ServiceRegistration.getRegistration",
93          query = "SELECT r from ServiceRegistration r "
94              + "where r.hostRegistration.baseUrl = :host and r.serviceType = :serviceType"
95      ),
96      @NamedQuery(
97          name = "ServiceRegistration.getAll",
98          query = "SELECT rh FROM ServiceRegistration rh WHERE rh.hostRegistration.active = true"
99      ),
100     @NamedQuery(
101         name = "ServiceRegistration.getAllOnline",
102         query = "SELECT rh FROM ServiceRegistration rh "
103             + "WHERE rh.hostRegistration.online=true AND rh.hostRegistration.active = true"
104     ),
105     @NamedQuery(
106         name = "ServiceRegistration.getByHost",
107         query = "SELECT rh FROM ServiceRegistration rh "
108         + "where rh.hostRegistration.baseUrl=:host AND rh.hostRegistration.active = true"
109     ),
110     @NamedQuery(
111         name = "ServiceRegistration.getByType",
112         query = "SELECT rh FROM ServiceRegistration rh "
113         + "where rh.serviceType=:serviceType AND rh.hostRegistration.active = true"
114     ),
115     @NamedQuery(
116         name = "ServiceRegistration.relatedservices.warning_error",
117         query = "SELECT rh FROM ServiceRegistration rh "
118         + "WHERE rh.serviceType = :serviceType AND (rh.serviceState = 1 OR rh.serviceState = 2)"
119     ),
120     @NamedQuery(
121         name = "ServiceRegistration.relatedservices.warning",
122         query = "SELECT rh FROM ServiceRegistration rh "
123         + "WHERE rh.serviceType = :serviceType AND rh.serviceState = 1"
124     ),
125 })
126 public class ServiceRegistrationJpaImpl implements ServiceRegistration {
127 
128   /** The logger */
129   private static final Logger logger = LoggerFactory.getLogger(ServiceRegistrationJpaImpl.class);
130 
131   @Id
132   @Column(name = "id")
133   @GeneratedValue
134   private Long id;
135 
136   @Column(name = "online_from")
137   @Temporal(TemporalType.TIMESTAMP)
138   private Date onlineFrom = new Date();
139 
140   @Column(name = "service_type", nullable = false, length = 255)
141   private String serviceType;
142 
143   @ManyToOne
144   @JoinColumn(name = "host_registration")
145   private HostRegistrationJpaImpl hostRegistration;
146 
147   @Column(name = "path", nullable = false, length = 255)
148   private String path;
149 
150   @Column(name = "service_state", nullable = false)
151   private int serviceState = ServiceState.NORMAL.ordinal();
152 
153   @Column(name = "state_changed")
154   @Temporal(TemporalType.TIMESTAMP)
155   private Date stateChanged = new Date();
156 
157   @Column(name = "warning_state_trigger")
158   private int warningStateTrigger;
159 
160   @Column(name = "error_state_trigger")
161   private int errorStateTrigger;
162 
163   @Column(name = "active", nullable = false)
164   private boolean active = true;
165 
166   @Column(name = "online", nullable = false)
167   private boolean online = true;
168 
169   @Column(name = "job_producer", nullable = false)
170   private boolean isJobProducer;
171 
172   @Transient
173   private boolean maintenanceMode = false;
174 
175   @Transient
176   private String host;
177 
178   /**
179    * Creates a new service registration which is online
180    */
181   public ServiceRegistrationJpaImpl() {
182   }
183 
184   /**
185    * Creates a new service registration which is online
186    *
187    * @param hostRegistration
188    *          the host registration
189    * @param serviceType
190    *          the type of job this service handles
191    * @param path
192    *          the URL path on this host to the service endpoint
193    */
194   public ServiceRegistrationJpaImpl(HostRegistrationJpaImpl hostRegistration, String serviceType, String path) {
195     this.hostRegistration = hostRegistration;
196     this.serviceType = serviceType;
197     this.path = path;
198   }
199 
200   /**
201    * Creates a new service registration which is online and not in maintenance mode.
202    *
203    * @param hostRegistration
204    *          the host registration
205    * @param serviceType
206    *          the type of job this service handles
207    * @param path
208    *          the URL path on this host to the service endpoint
209    * @param jobProducer
210    */
211   public ServiceRegistrationJpaImpl(HostRegistrationJpaImpl hostRegistration, String serviceType, String path,
212           boolean jobProducer) {
213     this.hostRegistration = hostRegistration;
214     this.host = hostRegistration.getBaseUrl();
215     this.serviceType = serviceType;
216     this.path = path;
217     this.isJobProducer = jobProducer;
218   }
219 
220   /**
221    * Gets the primary key for this service registration.
222    *
223    * @return the primary key
224    */
225   public Long getId() {
226     return id;
227   }
228 
229   /**
230    * Sets the primary key identifier.
231    *
232    * @param id
233    *          the identifier
234    */
235   public void setId(Long id) {
236     this.id = id;
237   }
238 
239   @Override
240   public Date getOnlineFrom() {
241     return onlineFrom;
242   }
243 
244   public void setOnlineFrom(Date onlineFrom) {
245     this.onlineFrom = onlineFrom;
246   }
247 
248   @Override
249   public String getServiceType() {
250     return serviceType;
251   }
252 
253   @Override
254   public String getPath() {
255     return path;
256   }
257 
258   public void setPath(String path) {
259     this.path = path;
260   }
261 
262   @Override
263   public ServiceState getServiceState() {
264     return ServiceState.values()[serviceState];
265   }
266 
267   public void setServiceState(ServiceState serviceState) {
268     this.serviceState = serviceState.ordinal();
269   }
270 
271   public void setServiceState(ServiceState state, int triggerJobSignature) {
272     setServiceState(state);
273     setStateChanged(new Date());
274     if (state == ServiceState.WARNING) {
275       setWarningStateTrigger(triggerJobSignature);
276     } else if (state == ServiceState.ERROR) {
277       setErrorStateTrigger(triggerJobSignature);
278     }
279   }
280 
281   @Override
282   public Date getStateChanged() {
283     return stateChanged;
284   }
285 
286   public void setStateChanged(Date stateChanged) {
287     this.stateChanged = stateChanged;
288   }
289 
290   @Override
291   public int getWarningStateTrigger() {
292     return warningStateTrigger;
293   }
294 
295   public void setWarningStateTrigger(int warningStateTrigger) {
296     this.warningStateTrigger = warningStateTrigger;
297   }
298 
299   @Override
300   public int getErrorStateTrigger() {
301     return errorStateTrigger;
302   }
303 
304   public void setErrorStateTrigger(int errorStateTrigger) {
305     this.errorStateTrigger = errorStateTrigger;
306   }
307 
308   @Override
309   public boolean isActive() {
310     return active;
311   }
312 
313   public void setActive(boolean isActive) {
314     this.active = isActive;
315   }
316 
317   @Override
318   public boolean isOnline() {
319     return online;
320   }
321 
322   public void setOnline(boolean online) {
323     if (online && !isOnline()) {
324       setOnlineFrom(new Date());
325     }
326     this.online = online;
327   }
328 
329   @Override
330   public boolean isJobProducer() {
331     return isJobProducer;
332   }
333 
334   public void setJobProducer(boolean isJobProducer) {
335     this.isJobProducer = isJobProducer;
336   }
337 
338   @Override
339   public boolean isInMaintenanceMode() {
340     return maintenanceMode;
341   }
342 
343   @Override
344   public String getHost() {
345     return host;
346   }
347 
348   /**
349    * Gets the associated {@link HostRegistrationJpaImpl}
350    *
351    * @return the host registration
352    */
353   public HostRegistrationJpaImpl getHostRegistration() {
354     return hostRegistration;
355   }
356 
357   /**
358    * @param hostRegistration
359    *          the hostRegistration to set
360    */
361   public void setHostRegistration(HostRegistrationJpaImpl hostRegistration) {
362     this.hostRegistration = hostRegistration;
363   }
364 
365   @PostLoad
366   public void postLoad() {
367     if (hostRegistration == null) {
368       logger.warn("host registration is null");
369     } else {
370       host = hostRegistration.getBaseUrl();
371       maintenanceMode = hostRegistration.isMaintenanceMode();
372       if (!hostRegistration.isOnline()) {
373         online = false;
374       }
375       if (!hostRegistration.isActive()) {
376         active = false;
377       }
378     }
379   }
380 
381   @Override
382   public int hashCode() {
383     return toString().hashCode();
384   }
385 
386   @Override
387   public boolean equals(Object obj) {
388     if (!(obj instanceof ServiceRegistration)) {
389       return false;
390     }
391     ServiceRegistration registration = (ServiceRegistration) obj;
392     return getHost().equals(registration.getHost()) && getServiceType().equals(registration.getServiceType());
393   }
394 
395   @Override
396   public String toString() {
397     return getServiceType() + "@" + getHost();
398   }
399 
400 }