/* ############################################################################### # # # Copyright (C) 2011-2016 OpenMEAP, Inc. # # Credits to Jonathan Schang & Rob Thacher # # # # Released under the LGPLv3 # # # # OpenMEAP is free software: you can redistribute it and/or modify # # it under the terms of the GNU Lesser General Public License as published # # by the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # OpenMEAP 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 Lesser General Public License for more details. # # # # You should have received a copy of the GNU Lesser General Public License # # along with OpenMEAP. If not, see <http://www.gnu.org/licenses/>. # # # ############################################################################### */ package com.openmeap.model.dto; import java.io.File; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; import org.apache.commons.lang.StringUtils; import com.openmeap.json.HasJSONProperties; import com.openmeap.json.JSONGetterSetter; import com.openmeap.json.JSONProperty; import com.openmeap.model.event.AbstractModelEntity; @Entity @Table(name="cluster_node") public class ClusterNode extends AbstractModelEntity implements HasJSONProperties { /** * Status resulting from the health check */ public static enum Status { CONNECT_ERROR, GOOD, ERROR } /** * This is the url to the deployment of openmeap-service-web.war * It is used for coordinating events from the server running * the openmeap-admin-web.war. */ private String serviceWebUrlPrefix; private String fileSystemStoragePathPrefix; private Long id; private Status lastStatus; private String lastStatusMessage; private Date lastStatusCheck; public ClusterNode() {} public ClusterNode(String serviceUrl, String prefix) { this.serviceWebUrlPrefix=serviceUrl; this.fileSystemStoragePathPrefix=prefix; } static final private JSONProperty[] jsonProperties = new JSONProperty[] { new JSONProperty("serviceWebUrlPrefix",String.class,new JSONGetterSetter(){ public Object getValue(Object src) { return ((ClusterNode)src).getServiceWebUrlPrefix(); } public void setValue(Object dest, Object value) { ((ClusterNode)dest).setServiceWebUrlPrefix((String)value); } }), new JSONProperty("fileSystemStoragePathPrefix",String.class,new JSONGetterSetter(){ public Object getValue(Object src) { return ((ClusterNode)src).getFileSystemStoragePathPrefix(); } public void setValue(Object dest, Object value) { ((ClusterNode)dest).setFileSystemStoragePathPrefix((String)value); } }) }; @Override @Transient public JSONProperty[] getJSONProperties() { return jsonProperties; } @Transient public Long getPk() { return getId(); } public void setPk( Object pkValue ) { setId((Long)pkValue); } @Id @GeneratedValue(strategy=GenerationType.AUTO) public Long getId() { return id; } public void setId(Long id) { this.id=id; } @Column(name="svc_web_url_prfx",length=256,unique=true) public String getServiceWebUrlPrefix() { return serviceWebUrlPrefix; } public void setServiceWebUrlPrefix(String serviceWebUrlPrefix) { this.serviceWebUrlPrefix = serviceWebUrlPrefix; } @Column(name="file_sys_strg_path_prfx", length=512) public String getFileSystemStoragePathPrefix() { return fileSystemStoragePathPrefix; } public void setFileSystemStoragePathPrefix(String fileSystemStoragePathPrefix) { this.fileSystemStoragePathPrefix = fileSystemStoragePathPrefix; } public String validateFileSystemStoragePathPrefix() { if( fileSystemStoragePathPrefix==null ) { return "File system storage path prefix should be set"; } File path = new File(fileSystemStoragePathPrefix); List<String> errors = new ArrayList<String>(); if( ! path.exists() ) { errors.add("does not exist"); } else { if( ! path.canWrite() ) { return "not writable"; } if( ! path.canRead() ) { return "not readable"; } } if( errors.size()>0 ) { StringBuilder sb = new StringBuilder("The path \""+fileSystemStoragePathPrefix+"\" has the following issues: "); sb.append(StringUtils.join(errors,",")); return sb.toString(); } return null; } public Map<Method,String> validate() { try { Map<Method,String> validationMap = new HashMap<Method,String>(); String validateFS = this.validateFileSystemStoragePathPrefix(); if(validateFS!=null) { validationMap.put(this.getClass().getMethod("getFileSystemStoragePathPrefix"), validateFS); } if( validationMap.size()>0 ) { return validationMap; } return null; } catch( NoSuchMethodException nsme ) { throw new RuntimeException(nsme); } } @Override public int hashCode() { return serviceWebUrlPrefix.hashCode() + fileSystemStoragePathPrefix.hashCode(); } @Override public boolean equals(Object o) { if( !(o instanceof ClusterNode)) return false; ClusterNode cn = (ClusterNode)o; return serviceWebUrlPrefix.equals(cn.getServiceWebUrlPrefix()); } synchronized public void setLastStatus(Status lastStatus) { this.lastStatus = lastStatus; } @Transient synchronized public Status getLastStatus() { return lastStatus; } synchronized public void setLastStatusMessage(String lastStatusMessage) { this.lastStatusMessage = lastStatusMessage; } @Transient synchronized public String getLastStatusMessage() { return lastStatusMessage; } synchronized public void setLastStatusCheck(Date lastStatusCheck) { this.lastStatusCheck = lastStatusCheck; } @Transient synchronized public Date getLastStatusCheck() { return lastStatusCheck; } }