/************************************************************************* * Copyright 2009-2015 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. ************************************************************************/ package com.eucalyptus.loadbalancing.activities; import java.util.Calendar; import java.util.Date; import javax.annotation.Nullable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.PersistenceContext; import javax.persistence.PostLoad; import javax.persistence.Table; import javax.persistence.Transient; import org.apache.log4j.Logger; import com.eucalyptus.entities.AbstractPersistent; import com.eucalyptus.entities.Entities; import com.eucalyptus.entities.TransactionResource; import com.eucalyptus.loadbalancing.LoadBalancer; import com.eucalyptus.loadbalancing.LoadBalancer.LoadBalancerEntityTransform; import com.eucalyptus.loadbalancing.LoadBalancerSecurityGroup; import com.eucalyptus.loadbalancing.LoadBalancerZone; import com.eucalyptus.loadbalancing.LoadBalancerZone.LoadBalancerZoneCoreView; import com.eucalyptus.loadbalancing.activities.LoadBalancerAutoScalingGroup.LoadBalancerAutoScalingGroupCoreView; import com.eucalyptus.util.Exceptions; import com.eucalyptus.util.TypeMapper; import com.eucalyptus.util.TypeMappers; import com.google.common.base.Function; /** * @author Sang-Min Park (spark@eucalyptus.com) * */ @Entity @PersistenceContext( name = "eucalyptus_loadbalancing" ) @Table( name = "metadata_servo_instance" ) public class LoadBalancerServoInstance extends AbstractPersistent { private static Logger LOG = Logger.getLogger( LoadBalancerServoInstance.class ); @Transient private static final long serialVersionUID = 1L; @Transient private LoadBalancerServoInstanceRelationView view = null; @PostLoad private void onLoad(){ if(this.view==null) this.view = new LoadBalancerServoInstanceRelationView(this); } public enum STATE { Pending, InService, Error, OutOfService, Retired } public enum DNS_STATE { Registered, Deregistered, None } @ManyToOne @JoinColumn( name = "metadata_zone_fk", nullable=true) private LoadBalancerZone zone = null; @ManyToOne @JoinColumn( name = "metadata_group_fk", nullable=true) private LoadBalancerSecurityGroup security_group = null; @ManyToOne @JoinColumn( name = "metadata_asg_fk", nullable=true) private LoadBalancerAutoScalingGroup autoscaling_group = null; @Transient private LoadBalancer loadbalancer = null; @Column(name="metadata_instance_id", nullable=false, unique=true) private String instanceId = null; @Column(name="metadata_state", nullable=false) private String state = null; @Column(name="metadata_address", nullable=true) private String address = null; @Column(name="metadata_private_ip", nullable=true) private String privateIp = null; @Column(name="metadata_dns_state", nullable=true) private String dnsState = null; @Column(name="metadata_certificate_expiration_date", nullable=true) private Date certificateExpirationDate = null; @Column(name="metadata_activity_failure_count", nullable=true) private Integer activityFailureCount = null; @Column(name="metadata_activity_failure_update_time", nullable=true) private Date activityFailureUpdateTime = null; private LoadBalancerServoInstance(){ } private LoadBalancerServoInstance(final LoadBalancerZone lbzone){ this.state = STATE.Pending.name(); this.zone = lbzone; try{ this.loadbalancer = LoadBalancerEntityTransform.INSTANCE.apply(zone.getLoadbalancer()); }catch(final Exception ex){ throw Exceptions.toUndeclared(ex); } } private LoadBalancerServoInstance(final LoadBalancerZone lbzone, final LoadBalancerSecurityGroup group){ this.state = STATE.Pending.name(); this.zone = lbzone; try{ this.loadbalancer = LoadBalancerEntityTransform.INSTANCE.apply(zone.getLoadbalancer()); }catch(final Exception ex){ throw Exceptions.toUndeclared(ex); } this.security_group = group; } public static LoadBalancerServoInstance newInstance(final LoadBalancerZone lbzone, final LoadBalancerSecurityGroup group, final LoadBalancerAutoScalingGroup as_group, final int certExpirationDays, String instanceId) { final LoadBalancerServoInstance instance = new LoadBalancerServoInstance(lbzone, group); instance.setInstanceId(instanceId); instance.setAutoScalingGroup(as_group); instance.dnsState = DNS_STATE.None.name(); final Calendar cal = Calendar.getInstance(); cal.setTime(new Date()); cal.add(Calendar.DATE, certExpirationDays); instance.setCertificateExpiration(cal.getTime()); return instance; } public static LoadBalancerServoInstance named(final LoadBalancerZone lbzone){ final LoadBalancerServoInstance sample = new LoadBalancerServoInstance(lbzone); return sample; } public static LoadBalancerServoInstance named(String instanceId){ final LoadBalancerServoInstance sample = new LoadBalancerServoInstance(); sample.instanceId = instanceId; return sample; } public static LoadBalancerServoInstance named(){ return new LoadBalancerServoInstance(); } public static LoadBalancerServoInstance withState(String state){ final LoadBalancerServoInstance sample = new LoadBalancerServoInstance(); sample.state = state; return sample; } public void setInstanceId(String id){ this.instanceId = id; } public String getInstanceId(){ return this.instanceId; } public void setState(STATE update){ this.state = update.name(); } public STATE getState(){ return Enum.valueOf(STATE.class, this.state); } public void setAddress(String address){ this.address=address; } public String getAddress(){ return this.address; } public void setSecurityGroup(LoadBalancerSecurityGroup group){ this.security_group=group; } public void setAutoScalingGroup(LoadBalancerAutoScalingGroup group){ this.autoscaling_group = group; } public void setAvailabilityZone(LoadBalancerZone zone){ this.zone = zone; } public LoadBalancerZoneCoreView getAvailabilityZone(){ return this.view.getZone(); } public LoadBalancerAutoScalingGroupCoreView getAutoScalingGroup() { return this.view.getAutoScalingGroup(); } public String getPrivateIp(){ return this.privateIp; } public void setPrivateIp(final String ipAddr){ this.privateIp = ipAddr; } public void setDnsState(final DNS_STATE dnsState){ this.dnsState = dnsState.toString(); } public DNS_STATE getDnsState(){ return Enum.valueOf(DNS_STATE.class, this.dnsState); } public void setCertificateExpiration(final Date expirationDate) { this.certificateExpirationDate = expirationDate; } public Date getCertificateExpiration() { return this.certificateExpirationDate; } public boolean isCertificateExpired() { if (this.certificateExpirationDate == null) return false; if ((new Date()).after(this.certificateExpirationDate)) return true; else return false; } public int getActivityFailureCount() { if (this.activityFailureCount == null ) return 0; else return this.activityFailureCount; } public void setActivityFailureCount(final int count) { this.activityFailureCount = count; } public Date getActivityFailureUpdateTime() { return this.activityFailureUpdateTime; } public void setActivityFailureUpdateTime(final Date updateTime) { this.activityFailureUpdateTime = updateTime; } @Override public String toString(){ String id = this.instanceId==null? "unassigned" : this.instanceId; return String.format("Servo-instance (%s) for %s", id, this.zone.getName()); } public static class LoadBalancerServoInstanceCoreView { private LoadBalancerServoInstance entity = null; LoadBalancerServoInstanceCoreView(final LoadBalancerServoInstance servo){ this.entity = servo; } public String getInstanceId(){ return this.entity.getInstanceId(); } public STATE getState(){ return this.entity.getState(); } public String getAddress(){ return this.entity. getAddress(); } public String getPrivateIp(){ return this.entity.getPrivateIp(); } public Date getCertificateExpirationDate() { return this.entity.getCertificateExpiration(); } public boolean isCertificateExpired() { return this.entity.isCertificateExpired(); } public boolean canResolveDns(){ return DNS_STATE.Registered.equals(this.entity.getDnsState()) && STATE.InService.equals(this.entity.getState()); } public static Function<LoadBalancerServoInstanceCoreView,String> address( ) { return StringFunctions.ADDRESS; } public static Function<LoadBalancerServoInstanceCoreView,String> privateIp( ) { return StringFunctions.PRIVATE_IP; } private enum StringFunctions implements Function<LoadBalancerServoInstanceCoreView,String> { ADDRESS { @Nullable @Override public String apply(@Nullable final LoadBalancerServoInstanceCoreView loadBalancerServoInstanceCoreView) { return loadBalancerServoInstanceCoreView.getAddress(); } }, PRIVATE_IP { @Nullable @Override public String apply(@Nullable final LoadBalancerServoInstanceCoreView loadBalancerServoInstanceCoreView) { return loadBalancerServoInstanceCoreView.getPrivateIp(); } },; } } @TypeMapper public enum LoadBalancerServoInstanceCoreViewTransform implements Function<LoadBalancerServoInstance, LoadBalancerServoInstanceCoreView> { INSTANCE; @Override public LoadBalancerServoInstanceCoreView apply( final LoadBalancerServoInstance servo ) { return new LoadBalancerServoInstanceCoreView( servo ); } } public enum LoadBalancerServoInstanceEntityTransform implements Function<LoadBalancerServoInstanceCoreView, LoadBalancerServoInstance> { INSTANCE; @Override @Nullable public LoadBalancerServoInstance apply( @Nullable LoadBalancerServoInstanceCoreView arg0) { try ( final TransactionResource db = Entities.transactionFor( LoadBalancerServoInstance.class ) ) { return Entities.uniqueResult(arg0.entity); }catch(final Exception ex){ throw Exceptions.toUndeclared(ex); } } } public static class LoadBalancerServoInstanceRelationView { private LoadBalancerZoneCoreView zone = null; private LoadBalancerAutoScalingGroupCoreView autoscaling_group = null; private LoadBalancerServoInstanceRelationView(final LoadBalancerServoInstance servo){ if(servo.zone!=null) this.zone = TypeMappers.transform(servo.zone, LoadBalancerZoneCoreView.class); if(servo.autoscaling_group!=null) this.autoscaling_group = TypeMappers.transform(servo.autoscaling_group, LoadBalancerAutoScalingGroupCoreView.class); } public LoadBalancerZoneCoreView getZone(){ return this.zone; } public LoadBalancerAutoScalingGroupCoreView getAutoScalingGroup() { return this.autoscaling_group; } } }