All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.kestra.jdbc.repository.AbstractJdbcServiceInstanceRepository Maven / Gradle / Ivy
Go to download
The modern, scalable orchestrator & scheduler open source platform
package io.kestra.jdbc.repository;
import io.kestra.core.repositories.ArrayListTotal;
import io.kestra.core.repositories.ServiceInstanceRepositoryInterface;
import io.kestra.core.server.Service;
import io.kestra.core.server.ServiceInstance;
import io.kestra.core.server.ServiceStateTransition;
import io.micronaut.data.model.Pageable;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.jooq.Configuration;
import org.jooq.DSLContext;
import org.jooq.Field;
import org.jooq.Record;
import org.jooq.Record1;
import org.jooq.SelectConditionStep;
import org.jooq.Table;
import org.jooq.TransactionalCallable;
import org.jooq.TransactionalRunnable;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.jooq.impl.DSL.using;
@Getter
@Slf4j
public abstract class AbstractJdbcServiceInstanceRepository extends AbstractJdbcRepository implements ServiceInstanceRepositoryInterface {
private static final Field STATE = field("state");
private static final Field TYPE = field("service_type");
private static final Field VALUE = field("value");
private static final Field UPDATED_AT = field("updated_at", Instant.class);
private static final Field CREATED_AT = field("created_at", Instant.class);
private static final Field SERVICE_ID = field("service_id");
protected io.kestra.jdbc.AbstractJdbcRepository jdbcRepository;
public AbstractJdbcServiceInstanceRepository(final io.kestra.jdbc.AbstractJdbcRepository jdbcRepository) {
this.jdbcRepository = jdbcRepository;
}
/**
* {@inheritDoc}
**/
@Override
public Optional findById(final String id) {
return jdbcRepository.getDslContextWrapper().transactionResult(
configuration -> findById(id, configuration, false)
);
}
public Optional findById(final String id,
final Configuration configuration,
final boolean isForUpdate) {
SelectConditionStep> query = using(configuration)
.select(VALUE)
.from(table())
.where(SERVICE_ID.eq(id));
return isForUpdate ?
this.jdbcRepository.fetchOne(query.forUpdate()) :
this.jdbcRepository.fetchOne(query);
}
/**
* {@inheritDoc}
**/
@Override
public List findAllInstancesInState(final Service.ServiceState state) {
return this.jdbcRepository.getDslContextWrapper()
.transactionResult(configuration -> {
SelectConditionStep> query = using(configuration)
.select(VALUE)
.from(table())
.where(STATE.eq(state.name()));
return this.jdbcRepository.fetch(query);
});
}
/**
* {@inheritDoc}
**/
@Override
public List findAllInstancesInStates(final Set states) {
return this.jdbcRepository.getDslContextWrapper()
.transactionResult(configuration -> findAllInstancesInStates(configuration, states, false));
}
/**
* {@inheritDoc}
**/
@Override
public List findAllInstancesBetween(final Service.ServiceType type, final Instant from, final Instant to) {
return jdbcRepository.getDslContextWrapper().transactionResult(configuration -> {
SelectConditionStep> query = using(configuration)
.select(VALUE)
.from(table())
.where(TYPE.eq(type.name()))
.and(CREATED_AT.lt(to))
.and(UPDATED_AT.ge(from));
return this.jdbcRepository.fetch(query);
});
}
public List findAllInstancesInStates(final Configuration configuration,
final Set states,
final boolean isForUpdate) {
SelectConditionStep> query = using(configuration)
.select(VALUE)
.from(table())
.where(STATE.in(states.stream().map(Enum::name).toList()));
return isForUpdate ?
this.jdbcRepository.fetch(query.forUpdate()) :
this.jdbcRepository.fetch(query);
}
/**
* Finds all service instances which are NOT {@link Service.ServiceState#RUNNING}.
*
* @return the list of {@link ServiceInstance}.
*/
public List findAllNonRunningInstances() {
return jdbcRepository.getDslContextWrapper().transactionResult(
configuration -> findAllNonRunningInstances(configuration, false)
);
}
/**
* Finds all service instances which are NOT {@link Service.ServiceState#RUNNING}.
*
* @return the list of {@link ServiceInstance}.
*/
public List findAllNonRunningInstances(final Configuration configuration,
final boolean isForUpdate) {
SelectConditionStep> query = using(configuration)
.select(VALUE)
.from(table())
.where(STATE.notIn(Service.ServiceState.CREATED.name(), Service.ServiceState.RUNNING.name()));
return isForUpdate ?
this.jdbcRepository.fetch(query.forUpdate()) :
this.jdbcRepository.fetch(query);
}
/**
* Finds all service instances which are {@link Service.ServiceState#NOT_RUNNING}.
*
* @return the list of {@link ServiceInstance}.
*/
public List findAllInstancesInNotRunningState() {
return jdbcRepository.getDslContextWrapper().transactionResult(
configuration -> findAllInstancesInNotRunningState(configuration, false)
);
}
/**
* Finds all service instances which are {@link Service.ServiceState#NOT_RUNNING}.
*
* @return the list of {@link ServiceInstance}.
*/
public List findAllInstancesInNotRunningState(final Configuration configuration,
final boolean isForUpdate) {
SelectConditionStep> query = using(configuration)
.select(VALUE)
.from(table())
.where(STATE.eq(Service.ServiceState.NOT_RUNNING.name()));
return isForUpdate ?
this.jdbcRepository.fetch(query.forUpdate()) :
this.jdbcRepository.fetch(query);
}
public void transaction(final TransactionalRunnable runnable) {
this.jdbcRepository
.getDslContextWrapper()
.transaction(runnable);
}
public T transactionResult(final TransactionalCallable runnable) {
return this.jdbcRepository
.getDslContextWrapper()
.transactionResult(runnable);
}
public void delete(DSLContext context, ServiceInstance instance) {
this.jdbcRepository.delete(context, instance);
}
/**
* {@inheritDoc}
**/
@Override
public void delete(final ServiceInstance instance) {
this.jdbcRepository.delete(instance);
}
/**
* {@inheritDoc}
**/
@Override
public ServiceInstance save(final ServiceInstance instance) {
this.jdbcRepository.persist(instance, this.jdbcRepository.persistFields(instance));
return instance;
}
/**
* {@inheritDoc}
**/
@Override
public List findAll() {
return this.jdbcRepository
.getDslContextWrapper()
.transactionResult(configuration -> this.jdbcRepository.fetch(
using(configuration).select(VALUE).from(table()))
);
}
/**
* {@inheritDoc}
**/
@Override
public ArrayListTotal find(final Pageable pageable,
final Set states,
final Set types) {
return this.jdbcRepository
.getDslContextWrapper()
.transactionResult(configuration -> {
DSLContext context = using(configuration);
SelectConditionStep> select = context.select(VALUE).from(table()).where("1=1");
if (states != null && !states.isEmpty()) {
select = select.and(STATE.in(states.stream().map(Enum::name).toList()));
}
if (types != null && !types.isEmpty()) {
select = select.and(TYPE.in(types.stream().map(Enum::name).toList()));
}
return this.jdbcRepository.fetchPage(context, select, pageable);
});
}
/**
* {@inheritDoc}
**/
@Override
public ServiceStateTransition.Response mayTransitionServiceTo(final ServiceInstance instance,
final Service.ServiceState newState,
final String reason) {
return transactionResult(configuration -> mayTransitServiceTo(configuration, instance, newState, reason));
}
/**
* Attempt to transition the state of a given service to given new state.
* This method may not update the service if the transition is not valid.
*
* @param instance the service instance.
* @param newState the new state of the service.
* @return an optional of the {@link ServiceInstance} or {@link Optional#empty()} if the service is not running.
*/
public ServiceStateTransition.Response mayTransitServiceTo(final Configuration configuration,
final ServiceInstance instance,
final Service.ServiceState newState,
final String reason) {
ImmutablePair result = mayUpdateStatusById(
configuration,
instance,
newState,
reason
);
return ServiceStateTransition.logTransitionAndGetResponse(instance, newState, result);
}
/**
* Attempt to transition the state of a given service to given new state.
* This method may not update the service if the transition is not valid.
*
* @param instance the new service instance.
* @param newState the new state of the service.
* @return an {@link Optional} of {@link ImmutablePair} holding the old (left), and new {@link ServiceInstance} or {@code null} if transition failed (right).
* Otherwise, an {@link Optional#empty()} if the no service can be found.
*/
private ImmutablePair mayUpdateStatusById(final Configuration configuration,
final ServiceInstance instance,
final Service.ServiceState newState,
final String reason) {
// Find the ServiceInstance to be updated
Optional optional = findById(instance.id(), configuration, true);
// Check whether service was found.
if (optional.isEmpty()) {
return null;
}
// Check whether the status transition is valid before saving.
final ServiceInstance before = optional.get();
if (before.state().isValidTransition(newState)) {
ServiceInstance updated = before
.state(newState, Instant.now(), reason)
.server(instance.server())
.metrics(instance.metrics());
return new ImmutablePair<>(before, save(updated));
}
return new ImmutablePair<>(before, null);
}
private Table table() {
return this.jdbcRepository.getTable();
}
/** {@inheritDoc} **/
@Override
public Function sortMapping() {
Map mapper = Map.of(
"createdAt", CREATED_AT.getName(),
"updatedAt", UPDATED_AT.getName(),
"serviceId", SERVICE_ID.getName()
);
return mapper::get;
}
}