Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ mta-assembly
.DS_Store
!com.sap.cloud.lm.sl.cf.process/src/test/resources/com/sap/cloud/lm/sl/cf/process/steps/web.zip
!multiapps-controller-client/src/test/resources/org/cloudfoundry/multiapps/controller/client/facade/staticfile.zip
**/.idea/
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,6 @@ public final class Messages {
public static final String FSS_CACHE_UPDATE_TIMEOUT = "Fss cache update timeout: {0} minutes";
public static final String THREAD_MONITOR_CACHE_TIMEOUT = "Flowable thread monitor cache timeout: {0} seconds";
public static final String SPACE_DEVELOPERS_CACHE_TIME_IN_SECONDS = "Cache for list of space developers per SpaceGUID: {0} seconds";
public static final String APP_SHUTDOWN_REQUEST = "Application with id:\"{0}\", instance id:\"{1}\", instance index:\"{2}\", is requested to shutdown. Timeout to wait before shutdown of Flowable job executor:\"{3}\" seconds.";
public static final String APP_SUCCESSFULLY_SHUTDOWN = "Application with id:\"{0}\", instance id:\"{1}\", instance index:\"{2}\", is shutdown. Timeout to wait before shutdown of Flowable job executor:\"{3}\" seconds.";
public static final String APP_SHUTDOWN_STATUS_MONITOR = "Monitor shutdown status of application with id:\"{0}\", instance id:\"{1}\", instance index:\"{2}\". Status:\"{3}\".";
public static final String CONTROLLER_CLIENT_SSL_HANDSHAKE_TIMEOUT_IN_SECONDS = "Controller client SSL handshake timeout in seconds: {0}";
public static final String CONTROLLER_CLIENT_CONNECT_TIMEOUT_IN_SECONDS = "Controller client connect timeout in seconds: {0}";
public static final String CONTROLLER_CLIENT_CONNECTION_POOL_SIZE = "Controller client connection pool size: {0}";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public final class Messages {
public static final String ERROR_GETTING_FILES_CREATED_AFTER_0_AND_BEFORE_1 = "Error getting files created after {0} and before {1]";
public static final String BACKUP_DESCRIPTOR_FOR_MTA_ID_0_AND_ID_1_ALREADY_EXIST = "Backup descriptor for mta id \"{0}\" and id \"{1}\" already exist";
public static final String BACKUP_DESCRIPTOR_WITH_ID_NOT_EXIST = "Backup descriptor with ID \"{0}\" does not exist";
public static final String APPLICATION_SHUTDOWN_WITH_APPLICATION_INSTANCE_ID_DOES_NOT_EXIST = "Application shutdown application instance ID \"{0}\" does not exist";
public static final String APPLICATION_SHUTDOWN_WITH_APPLICATION_INSTANCE_ID_ALREADY_EXIST = "Application shutdown application instance ID \"{0}\" already exist";
public static final String DATABASE_HEALTH_CHECK_FAILED = "Database health check failed";

// ERROR log messages:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
package org.cloudfoundry.multiapps.controller.core.model;
package org.cloudfoundry.multiapps.controller.persistence.dto;

import org.immutables.value.Value;
import java.util.Date;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.immutables.value.Value;

@Value.Immutable
@JsonSerialize(as = ImmutableApplicationShutdown.class)
@JsonDeserialize(as = ImmutableApplicationShutdown.class)
public interface ApplicationShutdown {

enum Status {
FINISHED, RUNNING
FINISHED, RUNNING, INITIAL
}

String getApplicationId();
String getId();

String getApplicationInstanceId();
String getApplicationId();

int getApplicationInstanceIndex();

Date getStartedAt();

@Value.Default
default Status getStatus() {
return Status.RUNNING;
return Status.INITIAL;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.cloudfoundry.multiapps.controller.persistence.dto;

import java.util.Date;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import org.cloudfoundry.multiapps.controller.persistence.model.PersistenceMetadata;

@Entity
@Table(name = PersistenceMetadata.TableNames.APPLICATION_SHUTDOWN_TABLE)
public class ApplicationShutdownDto implements DtoWithPrimaryKey<String> {

public static class AttributeNames {
private AttributeNames() {
}

public static final String ID = "id";
public static final String APPLICATION_ID = "applicationId";
public static final String APPLICATION_INSTANCE_INDEX = "applicationInstanceIndex";
public static final String SHUTDOWN_STATUS = "shutdownStatus";
public static final String STARTED_AT = "startedAt";
}

@Id
@Column(name = PersistenceMetadata.TableColumnNames.APPLICATION_SHUTDOWN_ID, nullable = false, unique = true)
private String id;

@Column(name = PersistenceMetadata.TableColumnNames.APPLICATION_SHUTDOWN_APPLICATION_INSTANCE_INDEX, nullable = false, unique = true)
private int applicationInstanceIndex;

@Column(name = PersistenceMetadata.TableColumnNames.APPLICATION_SHUTDOWN_APPLICATION_ID, nullable = false)
private String applicationId;

@Column(name = PersistenceMetadata.TableColumnNames.APPLICATION_SHUTDOWN_SHUTDOWN_STATUS, nullable = false)
private ApplicationShutdown.Status shutdownStatus;

@Column(name = PersistenceMetadata.TableColumnNames.APPLICATION_SHUTDOWN_STARTED_AT, nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date startedAt;

public ApplicationShutdownDto() {
// Required by JPA
}

public ApplicationShutdownDto(String id, String applicationId, int applicationInstanceIndex, ApplicationShutdown.Status shutdownStatus,
Date startedAt) {
this.id = id;
this.applicationId = applicationId;
this.applicationInstanceIndex = applicationInstanceIndex;
this.shutdownStatus = shutdownStatus;
this.startedAt = startedAt;
}

@Override
public String getPrimaryKey() {
return id;
}

@Override
public void setPrimaryKey(String id) {
this.id = id;
}

public String getАpplicationId() {
return applicationId;
}

public int getАpplicationIndex() {
return applicationInstanceIndex;
}

public ApplicationShutdown.Status getShutdownStatus() {
return shutdownStatus;
}

public Date getStartedAt() {
return startedAt;
}

@Override
public String toString() {
return "ApplicationShutdownDto{" +
"id='" + id + '\'' +
", applicationId='" + applicationId + '\'' +
", shutdownStatus='" + shutdownStatus + '\'' +
", applicationInstanceIndex='" + applicationInstanceIndex + '\'' +
", startedAt='" + startedAt + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ private TableNames() {
public static final String LOCK_OWNERS_TABLE = "lock_owners";
public static final String ASYNC_UPLOAD_JOB_TABLE = "async_upload_job";
public static final String BACKUP_DESCRIPTOR_TABLE = "backup_descriptor";
public static final String APPLICATION_SHUTDOWN_TABLE = "application_shutdown";

}

Expand Down Expand Up @@ -113,6 +114,12 @@ private TableColumnNames() {
public static final String BACKUP_DESCRIPTOR_SPACE_ID = "space_id";
public static final String BACKUP_DESCRIPTOR_NAMESPACE = "namespace";
public static final String BACKUP_DESCRIPTOR_TIMESTAMP = "timestamp";

public static final String APPLICATION_SHUTDOWN_ID = "id";
public static final String APPLICATION_SHUTDOWN_APPLICATION_INSTANCE_INDEX = "application_instance_index";
public static final String APPLICATION_SHUTDOWN_APPLICATION_ID = "application_id";
public static final String APPLICATION_SHUTDOWN_SHUTDOWN_STATUS = "shutdown_status";
public static final String APPLICATION_SHUTDOWN_STARTED_AT = "started_at";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.cloudfoundry.multiapps.controller.persistence.query;

import java.util.Date;

import org.cloudfoundry.multiapps.controller.persistence.dto.ApplicationShutdown;

public interface ApplicationShutdownQuery extends Query<ApplicationShutdown, ApplicationShutdownQuery> {

ApplicationShutdownQuery id(String instanceId);

ApplicationShutdownQuery applicationId(String applicationId);

ApplicationShutdownQuery applicationInstanceIndex(int applicationInstanceIndex);

ApplicationShutdownQuery shutdownStatus(ApplicationShutdown.Status shutdownStatus);

ApplicationShutdownQuery startedAt(Date startedAt);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package org.cloudfoundry.multiapps.controller.persistence.query.impl;

import java.util.Date;
import java.util.List;

import jakarta.persistence.EntityManager;
import org.cloudfoundry.multiapps.controller.persistence.dto.ApplicationShutdown;
import org.cloudfoundry.multiapps.controller.persistence.dto.ApplicationShutdownDto;
import org.cloudfoundry.multiapps.controller.persistence.dto.ApplicationShutdownDto.AttributeNames;
import org.cloudfoundry.multiapps.controller.persistence.query.ApplicationShutdownQuery;
import org.cloudfoundry.multiapps.controller.persistence.query.criteria.ImmutableQueryAttributeRestriction;
import org.cloudfoundry.multiapps.controller.persistence.query.criteria.QueryCriteria;
import org.cloudfoundry.multiapps.controller.persistence.services.ApplicationShutdownService;

public class ApplicationShutdownQueryImpl extends AbstractQueryImpl<ApplicationShutdown, ApplicationShutdownQuery>
implements ApplicationShutdownQuery {
private final QueryCriteria queryCriteria = new QueryCriteria();
private final ApplicationShutdownService.ApplicationShutdownMapper applicationShutdownMapper;

public ApplicationShutdownQueryImpl(EntityManager entityManager,
ApplicationShutdownService.ApplicationShutdownMapper applicationShutdownMapper) {
super(entityManager);
this.applicationShutdownMapper = applicationShutdownMapper;
}

@Override
public ApplicationShutdownQuery id(String instanceId) {
queryCriteria.addRestriction(ImmutableQueryAttributeRestriction.builder()
.attribute(AttributeNames.ID)
.condition(getCriteriaBuilder()::equal)
.value(instanceId)
.build());
return this;
}

@Override
public ApplicationShutdownQuery applicationId(String applicationId) {
queryCriteria.addRestriction(ImmutableQueryAttributeRestriction.builder()
.attribute(AttributeNames.APPLICATION_ID)
.condition(getCriteriaBuilder()::equal)
.value(applicationId)
.build());
return this;
}

@Override
public ApplicationShutdownQuery applicationInstanceIndex(int applicationInstanceIndex) {
queryCriteria.addRestriction(ImmutableQueryAttributeRestriction.builder()
.attribute(AttributeNames.APPLICATION_INSTANCE_INDEX)
.condition(getCriteriaBuilder()::equal)
.value(applicationInstanceIndex)
.build());
return this;
}

@Override
public ApplicationShutdownQuery shutdownStatus(ApplicationShutdown.Status shutdownStatus) {
queryCriteria.addRestriction(ImmutableQueryAttributeRestriction.builder()
.attribute(AttributeNames.SHUTDOWN_STATUS)
.condition(getCriteriaBuilder()::equal)
.value(shutdownStatus)
.build());
return this;
}

@Override
public ApplicationShutdownQuery startedAt(Date startedAt) {
queryCriteria.addRestriction(ImmutableQueryAttributeRestriction.builder()
.attribute(AttributeNames.STARTED_AT)
.condition(getCriteriaBuilder()::equal)
.value(startedAt)
.build());
return this;
}

@Override
public ApplicationShutdown singleResult() {
ApplicationShutdownDto dto = executeInTransaction(manager -> createQuery(manager, queryCriteria,
ApplicationShutdownDto.class).getResultList()
.stream()
.findFirst()
.orElse(null));
return dto != null ? applicationShutdownMapper.fromDto(dto) : null;
}

@Override
public List<ApplicationShutdown> list() {
List<ApplicationShutdownDto> dtos = executeInTransaction(manager -> createQuery(manager, queryCriteria,
ApplicationShutdownDto.class).getResultList());

return dtos.stream()
.map(applicationShutdownMapper::fromDto)
.toList();
}

@Override
public int delete() {
return executeInTransaction(manager -> createDeleteQuery(manager, queryCriteria, ApplicationShutdownDto.class).executeUpdate());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.cloudfoundry.multiapps.controller.persistence.services;

import jakarta.inject.Named;
import jakarta.persistence.EntityManagerFactory;
import org.cloudfoundry.multiapps.common.ConflictException;
import org.cloudfoundry.multiapps.common.NotFoundException;
import org.cloudfoundry.multiapps.controller.persistence.Messages;
import org.cloudfoundry.multiapps.controller.persistence.dto.ApplicationShutdown;
import org.cloudfoundry.multiapps.controller.persistence.dto.ApplicationShutdownDto;
import org.cloudfoundry.multiapps.controller.persistence.dto.ImmutableApplicationShutdown;
import org.cloudfoundry.multiapps.controller.persistence.query.ApplicationShutdownQuery;
import org.cloudfoundry.multiapps.controller.persistence.query.impl.ApplicationShutdownQueryImpl;

@Named
public class ApplicationShutdownService extends PersistenceService<ApplicationShutdown, ApplicationShutdownDto, String> {

private final ApplicationShutdownService.ApplicationShutdownMapper applicationShutdownMapper;

public ApplicationShutdownService(EntityManagerFactory entityManagerFactory,
ApplicationShutdownService.ApplicationShutdownMapper applicationShutdownMapper) {
super(entityManagerFactory);
this.applicationShutdownMapper = applicationShutdownMapper;
}

@Override
protected PersistenceObjectMapper<ApplicationShutdown, ApplicationShutdownDto> getPersistenceObjectMapper() {
return applicationShutdownMapper;
}

public ApplicationShutdownQuery createQuery() {
return new ApplicationShutdownQueryImpl(createEntityManager(), applicationShutdownMapper);
}

@Override
protected void onEntityConflict(ApplicationShutdownDto dto, Throwable t) {
throw new ConflictException(t, Messages.APPLICATION_SHUTDOWN_WITH_APPLICATION_INSTANCE_ID_ALREADY_EXIST, dto.getPrimaryKey());
}

@Override
protected void onEntityNotFound(String primaryKey) {
throw new NotFoundException(Messages.APPLICATION_SHUTDOWN_WITH_APPLICATION_INSTANCE_ID_DOES_NOT_EXIST, primaryKey);
}

@Named
public static class ApplicationShutdownMapper implements PersistenceObjectMapper<ApplicationShutdown, ApplicationShutdownDto> {

@Override
public ApplicationShutdown fromDto(ApplicationShutdownDto dto) {
return ImmutableApplicationShutdown.builder()
.id(dto.getPrimaryKey())
.applicationId(dto.getАpplicationId())
.applicationInstanceIndex(dto.getАpplicationIndex())
.status(dto.getShutdownStatus())
.startedAt(dto.getStartedAt())
.build();
}

@Override
public ApplicationShutdownDto toDto(ApplicationShutdown object) {
return new ApplicationShutdownDto(object.getId(), object.getApplicationId(), object.getApplicationInstanceIndex(),
object.getStatus(), object.getStartedAt());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
<class>org.cloudfoundry.multiapps.controller.persistence.dto.LockOwnerDto</class>
<class>org.cloudfoundry.multiapps.controller.persistence.dto.AsyncUploadJobDto</class>
<class>org.cloudfoundry.multiapps.controller.persistence.dto.BackupDescriptorDto</class>
<class>org.cloudfoundry.multiapps.controller.persistence.dto.ApplicationShutdownDto</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.weaving" value="static" />
<property name="eclipselink.weaving" value="static"/>
<property name="eclipselink.logging.logger"
value="org.eclipse.persistence.logging.slf4j.SLF4JLogger" />
value="org.eclipse.persistence.logging.slf4j.SLF4JLogger"/>
<property name="eclipselink.cache.shared.default" value="false"/>
</properties>
</persistence-unit>
Expand Down
Loading