/** * Licensed to The Apereo Foundation under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * * The Apereo Foundation licenses this file to you under the Educational * Community 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://opensource.org/licenses/ecl2.txt * * 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.opencastproject.serviceregistry.impl.jpa; import org.opencastproject.serviceregistry.api.ServiceRegistration; import org.opencastproject.serviceregistry.api.ServiceState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; import javax.persistence.Access; import javax.persistence.AccessType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.PostLoad; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; import javax.persistence.UniqueConstraint; /** * A record of a service that creates and manages receipts. */ @Entity(name = "ServiceRegistration") @Access(AccessType.FIELD) @Table(name = "mh_service_registration", uniqueConstraints = @UniqueConstraint(columnNames = { "host_registration", "service_type" })) @NamedQueries({ @NamedQuery(name = "ServiceRegistration.statistics", query = "SELECT job.processorServiceRegistration.id as serviceRegistration, job.status, " + "count(job.status) as numJobs, " + "avg(job.queueTime) as meanQueue, " + "avg(job.runTime) as meanRun FROM Job job " + "where job.dateCreated >= :minDateCreated and job.dateCreated <= :maxDateCreated " + "group by job.processorServiceRegistration.id, job.status"), @NamedQuery(name = "ServiceRegistration.hostloads", query = "SELECT job.processorServiceRegistration as serviceRegistration, job.status, sum(job.jobLoad) " + "FROM Job job " + "WHERE job.processorServiceRegistration.online=true and job.processorServiceRegistration.active=true and job.processorServiceRegistration.hostRegistration.maintenanceMode=false " + "and job.status in :statuses " + "GROUP BY job.processorServiceRegistration, job.status"), @NamedQuery(name = "ServiceRegistration.getRegistration", query = "SELECT r from ServiceRegistration r " + "where r.hostRegistration.baseUrl = :host and r.serviceType = :serviceType"), @NamedQuery(name = "ServiceRegistration.getAll", query = "SELECT rh FROM ServiceRegistration rh WHERE rh.hostRegistration.active = true"), @NamedQuery(name = "ServiceRegistration.getAllOnline", query = "SELECT rh FROM ServiceRegistration rh WHERE rh.hostRegistration.online=true AND rh.hostRegistration.active = true"), @NamedQuery(name = "ServiceRegistration.getByHost", query = "SELECT rh FROM ServiceRegistration rh " + "where rh.hostRegistration.baseUrl=:host AND rh.hostRegistration.active = true"), @NamedQuery(name = "ServiceRegistration.getByType", query = "SELECT rh FROM ServiceRegistration rh " + "where rh.serviceType=:serviceType AND rh.hostRegistration.active = true"), @NamedQuery(name = "ServiceRegistration.relatedservices.warning_error", query = "SELECT rh FROM ServiceRegistration rh " + "WHERE rh.serviceType = :serviceType AND (rh.serviceState = 1 OR rh.serviceState = 2)"), @NamedQuery(name = "ServiceRegistration.relatedservices.warning", query = "SELECT rh FROM ServiceRegistration rh " + "WHERE rh.serviceType = :serviceType AND rh.serviceState = 1"), @NamedQuery(name = "ServiceRegistration.countNotNormal", query = "SELECT count(rh) FROM ServiceRegistration rh " + "WHERE rh.serviceState <> 0 AND rh.hostRegistration.active = true") }) public class ServiceRegistrationJpaImpl implements ServiceRegistration { /** The logger */ private static final Logger logger = LoggerFactory.getLogger(ServiceRegistrationJpaImpl.class); @Id @Column(name = "id") @GeneratedValue private Long id; @Column(name = "online_from") @Temporal(TemporalType.TIMESTAMP) private Date onlineFrom = new Date(); @Column(name = "service_type", nullable = false, length = 255) private String serviceType; @ManyToOne @JoinColumn(name = "host_registration") private HostRegistrationJpaImpl hostRegistration; @Lob @Column(name = "path", nullable = false, length = 255) private String path; @Column(name = "service_state") private int serviceState = ServiceState.NORMAL.ordinal(); @Column(name = "state_changed") @Temporal(TemporalType.TIMESTAMP) private Date stateChanged = new Date(); @Column(name = "warning_state_trigger") private int warningStateTrigger; @Column(name = "error_state_trigger") private int errorStateTrigger; @Column(name = "active", nullable = false) private boolean active = true; @Column(name = "online", nullable = false) private boolean online = true; @Column(name = "job_producer", nullable = false) private boolean isJobProducer; @Transient private boolean maintenanceMode = false; @Transient private String host; /** * Creates a new service registration which is online */ public ServiceRegistrationJpaImpl() { } /** * Creates a new service registration which is online * * @param hostRegistration * the host registration * @param serviceType * the type of job this service handles * @param path * the URL path on this host to the service endpoint */ public ServiceRegistrationJpaImpl(HostRegistrationJpaImpl hostRegistration, String serviceType, String path) { this.hostRegistration = hostRegistration; this.serviceType = serviceType; this.path = path; } /** * Creates a new service registration which is online and not in maintenance mode. * * @param hostRegistration * the host registration * @param serviceType * the type of job this service handles * @param path * the URL path on this host to the service endpoint * @param jobProducer */ public ServiceRegistrationJpaImpl(HostRegistrationJpaImpl hostRegistration, String serviceType, String path, boolean jobProducer) { this.hostRegistration = hostRegistration; this.host = hostRegistration.getBaseUrl(); this.serviceType = serviceType; this.path = path; this.isJobProducer = jobProducer; } /** * Gets the primary key for this service registration. * * @return the primary key */ public Long getId() { return id; } /** * Sets the primary key identifier. * * @param id * the identifier */ public void setId(Long id) { this.id = id; } @Override public Date getOnlineFrom() { return onlineFrom; } public void setOnlineFrom(Date onlineFrom) { this.onlineFrom = onlineFrom; } @Override public String getServiceType() { return serviceType; } @Override public String getPath() { return path; } public void setPath(String path) { this.path = path; } @Override public ServiceState getServiceState() { return ServiceState.values()[serviceState]; } public void setServiceState(ServiceState serviceState) { this.serviceState = serviceState.ordinal(); } public void setServiceState(ServiceState state, int triggerJobSignature) { setServiceState(state); setStateChanged(new Date()); if (state == ServiceState.WARNING) { setWarningStateTrigger(triggerJobSignature); } else if (state == ServiceState.ERROR) { setErrorStateTrigger(triggerJobSignature); } } @Override public Date getStateChanged() { return stateChanged; } public void setStateChanged(Date stateChanged) { this.stateChanged = stateChanged; } @Override public int getWarningStateTrigger() { return warningStateTrigger; } public void setWarningStateTrigger(int warningStateTrigger) { this.warningStateTrigger = warningStateTrigger; } @Override public int getErrorStateTrigger() { return errorStateTrigger; } public void setErrorStateTrigger(int errorStateTrigger) { this.errorStateTrigger = errorStateTrigger; } @Override public boolean isActive() { return active; } public void setActive(boolean isActive) { this.active = isActive; } @Override public boolean isOnline() { return online; } public void setOnline(boolean online) { if (online && !isOnline()) setOnlineFrom(new Date()); this.online = online; } @Override public boolean isJobProducer() { return isJobProducer; } public void setJobProducer(boolean isJobProducer) { this.isJobProducer = isJobProducer; } @Override public boolean isInMaintenanceMode() { return maintenanceMode; } @Override public String getHost() { return host; } /** * Gets the associated {@link HostRegistrationJpaImpl} * * @return the host registration */ public HostRegistrationJpaImpl getHostRegistration() { return hostRegistration; } /** * @param hostRegistration * the hostRegistration to set */ public void setHostRegistration(HostRegistrationJpaImpl hostRegistration) { this.hostRegistration = hostRegistration; } @PostLoad public void postLoad() { if (hostRegistration == null) { logger.warn("host registration is null"); } else { host = hostRegistration.getBaseUrl(); maintenanceMode = hostRegistration.isMaintenanceMode(); if (!hostRegistration.isOnline()) online = false; if (!hostRegistration.isActive()) active = false; } } @Override public int hashCode() { return toString().hashCode(); } @Override public boolean equals(Object obj) { if (!(obj instanceof ServiceRegistration)) return false; ServiceRegistration registration = (ServiceRegistration) obj; return getHost().equals(registration.getHost()) && getServiceType().equals(registration.getServiceType()); } @Override public String toString() { return getServiceType() + "@" + getHost(); } }