/**
* Copyright (C) 2015 Orange
* Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
* 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 com.francetelecom.clara.cloud.coremodel;
import com.francetelecom.clara.cloud.commons.DateHelper;
import com.francetelecom.clara.cloud.commons.UUIDUtils;
import com.francetelecom.clara.cloud.model.DeploymentProfileEnum;
import com.francetelecom.clara.cloud.model.TechnicalDeploymentInstance;
import com.francetelecom.clara.cloud.techmodel.cf.Space;
import org.springframework.util.Assert;
import javax.persistence.*;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Date;
import java.util.Set;
/**
* Represents an Environment a deployment that is dedicated to a given
* application release for a given usage (e.g. "Paul's development environment
* for Springoo 1.0.1 release).
*/
@XmlRootElement
@Entity
@Table(name = "ENVIRONMENT")
@org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
public class Environment extends CoreItem {
private static final int UNIQUE_LABEL_MAX_SIZE = 100;
private static final String UNIQUE_LABEL_PREFIX = "env ";
private static final String TRUNCATE_SUFFIX = "...";
private static final long serialVersionUID = 253819499794917296L;
public static final String STATUS_MESSAGE_SUFFIX = "[...]";
/**
* Associated application release which defines the logical model.
*/
@ManyToOne
ApplicationRelease applicationRelease;
/**
* Primary owner of the environment. Implies the tenant used for selecting
* projection rules and software product catalog.
*/
@OneToOne
private PaasUser paasUser;
@OneToOne(cascade = CascadeType.ALL)
private TechnicalDeploymentInstance technicalDeploymentInstance;
/**
* environment creation date
*/
public static final String CREATION_DATE = "creationDate";
protected Date creationDate;
/**
* environment deletion date (should be null if environment is not REMOVED)
*/
protected Date deletionDate;
@Enumerated(EnumType.STRING)
private DeploymentProfileEnum type;
@Enumerated(EnumType.STRING)
private EnvironmentStatus status;
/**
* Status message
*/
@Column(length = 5000)
private String statusMessage;
/**
* Percentage of progress, -1 if not set
*/
private int statusPercent = -1;
/**
* environment label. this label is set by user when creating environment.
*/
private String label;
@Size(min = 0, max = 255)
private String comment;
/**
*
* @param type
* environment type
* @param applicationRelease
* application release
* @param paasUser
* environment owner
* @param tdi
* technical deployment instance
*/
public Environment(DeploymentProfileEnum type, String label, ApplicationRelease applicationRelease, PaasUser paasUser, TechnicalDeploymentInstance tdi) {
super(UUIDUtils.generateUUID("e"));
Assert.notNull(type, "cannot create environment : environment type should not be null");
Assert.notNull(applicationRelease, "cannot create environment : environment release should not be null");
Assert.hasText(label, "cannot create environment : environment label should not be empty");
Assert.notNull(tdi, "cannot create environment : technical deployment instance should not be null");
this.type = type;
this.label = label;
this.applicationRelease = applicationRelease;
setOwner(paasUser);
this.technicalDeploymentInstance = tdi;
this.status = EnvironmentStatus.CREATING;
this.creationDate = DateHelper.getNow();
this.deletionDate = null;
}
public Environment() {
}
public ApplicationRelease getApplicationRelease() {
return applicationRelease;
}
/**
* Accesses the current state stored in DB.
*
* Beware that this is currently modified directly by the activation using
* directly DAOs, and without going through setter on this class. (see
* ActivationTaskHandlerCallback.handleRequest())
*
* @return status of the environment
*/
public EnvironmentStatus getStatus() {
return this.status;
}
/**
* used by Entite::toString() introspection
*
* @return
*/
public String getStatusString() {
return getStatus().toString();
}
/**
* Sets the current status. Set percent to 0 and reset status message.
*
* Beware that this is currently modified directly by the activation using
* directly DAOs, and without going through setter on this class. (see
* ActivationTaskHandlerCallback.handleRequest())
*
* @param status
* status to set
*/
public void setStatus(EnvironmentStatus status) {
if (status.equals(this.status)) {
return;
}
this.status = status;
this.statusMessage = "";
this.statusPercent = 0;
this.deletionDate = null;
if (EnvironmentStatus.REMOVED.equals(status)) {
deletionDate = DateHelper.getNow();
}
}
public PaasUser getPaasUser() {
return paasUser;
}
private void setOwner(PaasUser paasUser) {
Assert.notNull(paasUser, "environment owner should not be null");
this.paasUser = paasUser;
}
public DeploymentProfileEnum getType() {
return type;
}
public TechnicalDeploymentInstance getTechnicalDeploymentInstance() {
return technicalDeploymentInstance;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public Date getCreationDate() {
return creationDate;
}
public Date getDeletionDate() {
return deletionDate;
}
public String getStatusMessage() {
return statusMessage;
}
public void setStatusMessage(String statusMessage) {
this.statusMessage = statusMessage;
}
public int getStatusPercent() {
return statusPercent;
}
public void setStatusPercent(int statusPercent) {
this.statusPercent = statusPercent;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public void setAndTruncateStatusMessage(String message) {
// To change body of created methods use File | Settings | File
// Templates.
if (message != null && message.length() > 5000) {
message = message.substring(0, 4994) + STATUS_MESSAGE_SUFFIX;
}
statusMessage = message;
}
/**
* Build and return a unique environment label by prefixing label with uid
* in the form <uid>: <label>. The generated string is truncated to 100
* characters.
*
* @return the generated label.
*/
public String getUniqueLabel() {
String uniqueLabel = UNIQUE_LABEL_PREFIX + this.getUID() + ": " + this.getLabel();
if (uniqueLabel.length() > UNIQUE_LABEL_MAX_SIZE) {
uniqueLabel = uniqueLabel.substring(0, UNIQUE_LABEL_MAX_SIZE - TRUNCATE_SUFFIX.length());
uniqueLabel += TRUNCATE_SUFFIX;
}
return uniqueLabel;
}
/**
* This generate the log used by splunk (ie. to construct splunk dashboard)
*
* @return
*/
public String toLogString() {
StringBuilder sbInfoMsg = new StringBuilder();
sbInfoMsg.append("createEnvironment query finished: id=").append(getTechnicalDeploymentInstance().getId()).append(", releaseUID=").append(getApplicationRelease().getUID())
.append(", type=").append(getType()).append(", label=").append(getLabel()).append(", EnvTdiName=").append(getTechnicalDeploymentInstance().getName());
return sbInfoMsg.toString();
}
public boolean isStopped() {
return getStatus().equals(EnvironmentStatus.STOPPED);
}
public boolean isFailed() {
return getStatus().equals(EnvironmentStatus.FAILED);
}
public boolean isRunning() {
return getStatus().equals(EnvironmentStatus.RUNNING);
}
public boolean isStarting() {
return getStatus().equals(EnvironmentStatus.STARTING);
}
public boolean isStopping() {
return getStatus().equals(EnvironmentStatus.STOPPING);
}
public boolean isRemoving() {
return getStatus().equals(EnvironmentStatus.REMOVING);
}
public boolean isRemoved() {
return getStatus().equals(EnvironmentStatus.REMOVED);
}
public String getInternalName() {
Set<Space> spaces = technicalDeploymentInstance.getTechnicalDeployment().listXaasSubscriptionTemplates(Space.class);
return ((spaces.size() == 1) ? spaces.iterator().next().getSpaceName().getValue() : "undefined");
}
public void updateStatus(EnvironmentStatus newStatus, String message, int percent) {
if (newStatus != null) {
setStatus(newStatus);
}
setAndTruncateStatusMessage(message);
if (percent > 100) {
setStatusPercent(100);
} else if (percent < 0) {
setStatusPercent(-1);
} else {
setStatusPercent(percent);
}
}
public ActivationContext getActivationContext() {
return new ActivationContext(getUID(), getLabel());
}
}