Skip to content

Commit

Permalink
fix error when sending mail for archived deployment, fix sending mail…
Browse files Browse the repository at this point in the history
… on predeploy failure
  • Loading branch information
yvespp committed Dec 14, 2023
1 parent 1ac8656 commit 883e4ce
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1024,25 +1024,25 @@ private void updateDeploymentStatusMessage(final List<DeploymentEntity> deployme
* @param resourceId - the ApplicationServe used for deployment
* @param generationResult
* @param reason - the DeploymentFailureReason (if any)
* @return - the updated deployment
*/
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public DeploymentEntity updateDeploymentInfo(GenerationModus generationModus, final Integer deploymentId, final String errorMessage, final Integer resourceId,
final GenerationResult generationResult, DeploymentFailureReason reason) {
// don't lock a deployment for predeployment as there is no need to update the deployment.
if (GenerationModus.PREDEPLOY.equals(generationModus) && errorMessage == null) {
if (GenerationModus.PREDEPLOY == generationModus && errorMessage == null) {
log.fine("Predeploy script finished at " + new Date());
return em.find(DeploymentEntity.class, deploymentId);
}
DeploymentEntity deployment = em.find(DeploymentEntity.class, deploymentId,
LockModeType.PESSIMISTIC_FORCE_INCREMENT);
DeploymentEntity deployment = em.find(DeploymentEntity.class, deploymentId, LockModeType.PESSIMISTIC_FORCE_INCREMENT);

// set as used for deployment
if (resourceId != null) {
ResourceEntity as = em.find(ResourceEntity.class, resourceId);
deployment.setResource(as);
}

if (GenerationModus.DEPLOY.equals(generationModus)) {
if (GenerationModus.DEPLOY == generationModus) {
if (errorMessage == null) {
String nodeInfo = getNodeInfoForDeployment(generationResult);
deployment.appendStateMessage("Successfully deployed at " + new Date() + "\n" + nodeInfo);
Expand All @@ -1055,7 +1055,7 @@ public DeploymentEntity updateDeploymentInfo(GenerationModus generationModus, fi
}
deployment.setReason(reason);
}
} else if (GenerationModus.PREDEPLOY.equals(generationModus)) {
} else if (GenerationModus.PREDEPLOY == generationModus) {
deployment.appendStateMessage(errorMessage);
deployment.setDeploymentState(DeploymentState.failed);
if (reason == null) {
Expand Down Expand Up @@ -1126,7 +1126,6 @@ public void createShakedownTestForTrackinIdOfDeployment(Integer trackingId) {
* single email notification if all of them are executed (independent of their success state).
*/
public void sendOneNotificationForTrackingIdOfDeployment(Integer trackingId) {
// hole alle deployments mit derselben trackingId
List<DeploymentEntity> deploymentsWithSameTrackingId = getDeplyomentsWithSameTrackingId(trackingId);

if (isAllDeploymentsWithSameTrackingIdExecuted(deploymentsWithSameTrackingId)) {
Expand All @@ -1136,8 +1135,7 @@ public void sendOneNotificationForTrackingIdOfDeployment(Integer trackingId) {

private boolean isAllDeploymentsWithSameTrackingIdExecuted(List<DeploymentEntity> deploymentsWithSameTrackingId) {
for (final DeploymentEntity deploymentEntity : deploymentsWithSameTrackingId) {
// not executed and not failed, failed and executed Deployments are complete
if (!deploymentEntity.isExecuted() && !DeploymentState.failed.equals(deploymentEntity.getDeploymentState())) {
if (!deploymentEntity.isExecuted()) {
return false;
}
}
Expand All @@ -1160,7 +1158,6 @@ private List<DeploymentEntity> getDeplyomentsWithSameTrackingId(Integer tracking
* @param deployments
*/
private void sendsNotificationAndUpdatedStatusOfDeployments(final List<DeploymentEntity> deployments) {

if (deployments != null && !deployments.isEmpty()) {
String message = deploymentNotificationService.createAndSendMailForDeplyoments(deployments);
updateDeploymentStatusMessage(deployments, message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@
package ch.puzzle.itc.mobiliar.business.deploy.control;

import ch.puzzle.itc.mobiliar.business.generator.control.extracted.ResourceDependencyResolverService;
import ch.puzzle.itc.mobiliar.business.releasing.control.ReleaseMgmtService;
import ch.puzzle.itc.mobiliar.business.usersettings.control.UserSettingsService;
import ch.puzzle.itc.mobiliar.business.resourcerelation.entity.ConsumedResourceRelationEntity;
import ch.puzzle.itc.mobiliar.business.deploy.entity.DeploymentEntity;
import ch.puzzle.itc.mobiliar.business.releasing.entity.ReleaseEntity;
import ch.puzzle.itc.mobiliar.business.resourcegroup.entity.ResourceEntity;
import ch.puzzle.itc.mobiliar.business.utils.notification.NotificationService;
import ch.puzzle.itc.mobiliar.common.util.ConfigurationService;
import ch.puzzle.itc.mobiliar.common.util.ConfigKey;
Expand Down Expand Up @@ -55,44 +52,35 @@ public class DeploymentNotificationService {
@Inject
private ResourceDependencyResolverService resourceDependencyResolverService;

@Inject
private ReleaseMgmtService releaseMgmtService;

@Inject
private Logger log;

/**
* Creates a notification email for deployment executions and sends them to
* the given receipients
* the given recipients
*
* @param deployments
* - the executed deployments
* @return the message to be stored with the deployment.
* @throws AddressException
* @throws MessagingException
*/
public String createAndSendMailForDeplyoments(
final List<DeploymentEntity> deployments) {
public String createAndSendMailForDeplyoments(final List<DeploymentEntity> deployments) {
String message = null;

// do nothing if no deployment is available
if (deployments != null && !deployments.isEmpty()) {
String subjectMessage = "AMW-Deploy for tracking id: "
+ deployments.get(0).getTrackingId();

try {
Address[] emailReceipients = getAllReceipients(deployments);

if (notificationService.createAndSendMail(subjectMessage,
getMessageContentForDeployments(deployments),
emailReceipients)) {
message = getSuccessfulSendMailToReceipientMessage(emailReceipients);
}
} catch (MessagingException e) {
message = getFailureSendMailMessage(e.getMessage());
log.log(Level.WARNING, "Deployment notification ("
+ subjectMessage + ") could not be sent", e);
if (deployments == null || deployments.isEmpty()) {
return message;
}
String subjectMessage = "Liima-Deploy for tracking id: " + deployments.get(0).getTrackingId();

try {
Address[] emailRecipients = getAllRecipients(deployments);
if (notificationService.createAndSendMail(subjectMessage, getMessageContentForDeployments(deployments), emailRecipients)) {
message = getSuccessfulSendMailToRecipientMessage(emailRecipients);
}
} catch (MessagingException e) {
message = getFailureSendMailMessage(e.getMessage());
log.log(Level.WARNING, "Deployment notification (" + subjectMessage + ") could not be sent", e);
}

return message;
Expand All @@ -105,8 +93,7 @@ public String createAndSendMailForDeplyoments(
* - the deployments for which the email shall be generated.
* @return the e-mail content to be sent
*/
private String getMessageContentForDeployments(
final List<DeploymentEntity> deployments) {
private String getMessageContentForDeployments(final List<DeploymentEntity> deployments) {
final StringBuffer message = new StringBuffer();
for (final DeploymentEntity deployment : deployments) {
message.append("Application server: ").append(deployment.getResourceGroup().getName());
Expand Down Expand Up @@ -140,60 +127,47 @@ private String getApplicationWithVersionsString(DeploymentEntity deploymentEntit
}

/**
* Extracts the receipients interested in getting notifications about the
* Extracts the recipients interested in getting notifications about the
* deployment execution.
*
* @param deployments
* @return - an array of e-mail addresses
* @throws AddressException
*/
private Address[] getAllReceipients(final List<DeploymentEntity> deployments)
private Address[] getAllRecipients(final List<DeploymentEntity> deployments)
throws AddressException {

final Set<String> emailReceipients = new HashSet<String>();
final Set<String> emailRecipients = new HashSet<String>();
final Set<Integer> groupIds = new HashSet<Integer>();

for (final DeploymentEntity deployment : deployments) {
if (deployment.isSendEmail()) {
emailReceipients.add(deployment.getDeploymentRequestUser());
emailRecipients.add(deployment.getDeploymentRequestUser());
}
if (deployment.isSendEmailConfirmation()) {
emailReceipients
.add(deployment.getDeploymentConfirmationUser());
emailRecipients.add(deployment.getDeploymentConfirmationUser());
}
ReleaseEntity release = deployment.getRelease();
if(release == null){
// get Past Release
release = releaseMgmtService.getDefaultRelease();

// skip notification of favorites if deployment is preserved
if (deployment.isPreserved()) {
continue;
}
groupIds.add(deployment.getResourceGroup().getId());
if (deployment.getResource().getConsumedMasterRelations() == null) {
continue;
}
// Find the resourceGroup ids for the deployment
final ResourceEntity resource = resourceDependencyResolverService.getResourceEntityForRelease(deployment.getResourceGroup(),
release);
if (resource != null) {
groupIds.add(resource.getResourceGroup().getId());
if (resource.getConsumedMasterRelations() != null) {
for (final ConsumedResourceRelationEntity rel : resourceDependencyResolverService
.getConsumedMasterRelationsForRelease(resource,
deployment.getRelease())) {
groupIds.add(rel.getSlaveResource().getResourceGroup().getId());
}
}
for (final ConsumedResourceRelationEntity rel : resourceDependencyResolverService.getConsumedMasterRelationsForRelease(deployment.getResource(), deployment.getRelease())) {
groupIds.add(rel.getSlaveResource().getResourceGroup().getId());
}
}

List<String> userNames = userSettingsService
.getRegisteredUsernamesForResourcesIds(groupIds);
emailReceipients.addAll(userNames);
emailRecipients.addAll(userSettingsService.getRegisteredUsernamesForResourcesIds(groupIds));

final Address[] to = new InternetAddress[emailReceipients.size()];

final Address[] to = new InternetAddress[emailRecipients.size()];
int i = 0;
for (final String user : emailReceipients) {
// TODO make configurable
to[i++] = new InternetAddress(user + "@"
+ ConfigurationService.getProperty(ConfigKey.MAIL_DOMAIN));
for (final String user : emailRecipients) {
to[i++] = new InternetAddress(user + "@" + ConfigurationService.getProperty(ConfigKey.MAIL_DOMAIN));
}

return to;
}

Expand All @@ -211,15 +185,15 @@ private String getFailureSendMailMessage(final String e) {
/**
* Generates a success message for email sending process.
*
* @param emailReceipients
* - the receipients to which the email was successfully sent
* @param emailRecipients
* - the recipients to which the email was successfully sent
* @return
*/
private String getSuccessfulSendMailToReceipientMessage(
final Address[] emailReceipients) {
private String getSuccessfulSendMailToRecipientMessage(
final Address[] emailRecipients) {
final StringBuffer result = new StringBuffer(
"Notification email sent to following receipients: \n");
for (final Address address : emailReceipients) {
"Notification email sent to following recipients: \n");
for (final Address address : emailRecipients) {
result.append(address.toString());
result.append("\n");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,31 @@
import ch.puzzle.itc.mobiliar.business.resourcegroup.entity.ResourceGroupEntity;
import ch.puzzle.itc.mobiliar.business.shakedown.entity.ShakedownTestEntity;
import ch.puzzle.itc.mobiliar.common.exception.DeploymentStateException;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.Getter;
import lombok.Setter;

import lombok.ToString;
import lombok.SneakyThrows;

import org.hibernate.annotations.BatchSize;

import javax.persistence.*;

import java.io.Serializable;
import java.io.StringReader;
import java.util.*;


/**
* Entity implementation class for Entity: Deployment
*/
@Entity
@ToString
@Table(name = "TAMW_deployment")
@NamedQuery(name = DeploymentEntity.LAST_SUCCESSFUL_DEPLOYMENT, query = "select d from DeploymentEntity d where d.deploymentDate=(select max(t.deploymentDate) from DeploymentEntity t where t.context=:context and t.resourceGroup=:resourceGroup and t.release=:release and t.deploymentState=:deploymentState)")
public class DeploymentEntity implements Serializable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import ch.puzzle.itc.mobiliar.common.exception.GeneratorException.MISSING;
import ch.puzzle.itc.mobiliar.common.exception.ResourceNotFoundException;
import ch.puzzle.itc.mobiliar.common.util.DefaultResourceTypeDefinition;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

Expand Down Expand Up @@ -425,24 +426,18 @@ public EnvironmentGenerationResult generateApplicationServerConfigurationForEnvi
*/
private void handleException(GenerationModus generationModus, final Exception e,
final DeploymentEntity deployment) {
log.log(Level.WARNING, "Deployment fehlgeschlagen", e);
String message = generationModus.getAction() + " failure at " + new Date() + ". Reason: " + e
.getMessage() + "\n";
log.log(Level.WARNING, String.format("Deployment %d failed ",deployment.getId()), e);
String message = generationModus.getAction() + " failure at " + new Date() + ". Reason: " + e.getMessage() + "\n";
DeploymentFailureReason reason = (e instanceof GeneratorException && ((GeneratorException) e).getMissingObject().equals(MISSING.NODE)) ?
DeploymentFailureReason.NODE_MISSING : null;
deploymentBoundary.updateDeploymentInfo(generationModus, deployment.getId(), message,
deployment.getResource() != null ? deployment.getResource()
.getId() : null, null, reason);
if (generationModus.isSendNotificationOnErrorGenerationModus()) {
deploymentBoundary.sendOneNotificationForTrackingIdOfDeployment(deployment.getTrackingId());
}
deploymentBoundary.updateDeploymentInfoAndSendNotification(generationModus, deployment.getId(), message,
deployment.getResource() != null ? deployment.getResource().getId() : null, null, reason);
}

/**
* Handle exceptions in the preparation of the deployment.
*/
private void handleExceptions(GenerationModus generationModus, GenerationResult generationResult,
final DeploymentEntity deployment) {
private void handleExceptions(GenerationModus generationModus, GenerationResult generationResult, DeploymentEntity deployment) {

StringBuilder message = new StringBuilder(generationModus.getAction() + " failure at " + new Date() + ". Reasons: ");
if (generationResult.hasErrors()) {
Expand All @@ -457,12 +452,9 @@ private void handleExceptions(GenerationModus generationModus, GenerationResult
}
}

log.log(Level.WARNING, "Deployment fehlgeschlagen \n" + message.toString());
deploymentBoundary.updateDeploymentInfo(generationModus, deployment.getId(), message.toString(),
log.log(Level.WARNING, String.format("Deployment %d failed: %s", deployment.getId(), message));
deploymentBoundary.updateDeploymentInfoAndSendNotification(generationModus, deployment.getId(), message.toString(),
deployment.getResource() != null ? deployment.getResource().getId() : null, generationResult, reason);
if (generationModus.isSendNotificationOnErrorGenerationModus()) {
deploymentBoundary.sendOneNotificationForTrackingIdOfDeployment(deployment.getTrackingId());
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ public void setAction(String action) {
* @return
*/
public boolean isSendNotificationOnErrorGenerationModus(){
return (DEPLOY.equals(this) || PREDEPLOY.equals(this));
return DEPLOY == this || PREDEPLOY == this;
}

/**
* Send Email Success Notification only when Deployment
* @return
*/
public boolean isSendNotificationOnSuccessGenerationModus(){
return (DEPLOY.equals(this));
return DEPLOY == this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@

package ch.puzzle.itc.mobiliar.business.utils.notification;

import java.util.logging.Logger;

import javax.annotation.Resource;
import javax.inject.Inject;
import javax.mail.*;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.MimeMessage;
import java.util.logging.Logger;

public class MailService {

Expand All @@ -36,20 +41,20 @@ public class MailService {
@Inject
private Logger log;

public boolean createMessageAndSend(String subject, String content, Address[] emailReceipients) throws MessagingException{
public boolean createMessageAndSend(String subject, String content, Address[] emailRecipients) throws MessagingException{
if (mailSession == null) {
String addresses = "";
if(emailReceipients != null) {
for (Address address : emailReceipients) {
if(emailRecipients != null) {
for (Address address : emailRecipients) {
addresses += address.toString() + ", ";
}
}
log.warning("Mail session not available, unable to send Mail(subject: " +subject+", content: "+content+" ) to Receipients: " + addresses);
log.warning("Mail session not available, unable to send Mail(subject: " +subject+", content: "+content+" ) to Recipients: " + addresses);
return false;
}

final MimeMessage mail = new MimeMessage(mailSession);
mail.setRecipients(Message.RecipientType.TO, emailReceipients);
mail.setRecipients(Message.RecipientType.TO, emailRecipients);
mail.setSubject(subject);
mail.setContent(content, CONTENT_TYPE);
mail.setSentDate(new java.util.Date());
Expand Down
Loading

0 comments on commit 883e4ce

Please sign in to comment.