package io.cattle.platform.core.dao.impl; import static io.cattle.platform.core.model.tables.ScheduledUpgradeTable.*; import static io.cattle.platform.core.model.tables.ServiceTable.*; import static io.cattle.platform.core.model.tables.StackTable.*; import io.cattle.platform.core.constants.CommonStatesConstants; import io.cattle.platform.core.constants.ServiceConstants; import io.cattle.platform.core.dao.StackDao; import io.cattle.platform.core.model.ScheduledUpgrade; import io.cattle.platform.core.model.Stack; import io.cattle.platform.core.model.tables.records.ScheduledUpgradeRecord; import io.cattle.platform.core.model.tables.records.StackRecord; import io.cattle.platform.db.jooq.dao.impl.AbstractJooqDao; import io.cattle.platform.object.ObjectManager; import io.github.ibuildthecloud.gdapi.id.IdFormatter; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.inject.Inject; import javax.inject.Named; import org.jooq.Record2; import org.jooq.RecordHandler; import org.jooq.impl.DSL; @Named public class StackDaoImpl extends AbstractJooqDao implements StackDao { @Inject ObjectManager objectManager; @Override public Stack getStackByExternalId(Long accountId, String externalId) { return create().selectFrom(STACK) .where(STACK.ACCOUNT_ID.eq(accountId)) .and(STACK.REMOVED.isNull()) .and(STACK.EXTERNAL_ID.eq(externalId)) .fetchAny(); } @Override public Map<Long, List<Object>> getServicesForStack(List<Long> ids, final IdFormatter idFormatter) { final Map<Long, List<Object>> result = new HashMap<>(); create().select(SERVICE.ID, SERVICE.STACK_ID) .from(SERVICE) .where(SERVICE.STACK_ID.in(ids) .and(SERVICE.REMOVED.isNull())) .fetchInto(new RecordHandler<Record2<Long, Long>>() { @Override public void next(Record2<Long, Long> record) { Long id = record.getValue(SERVICE.ID); Long stackId = record.getValue(SERVICE.STACK_ID); List<Object> list = result.get(stackId); if (list == null) { list = new ArrayList<>(); result.put(stackId, list); } list.add(idFormatter.formatId(ServiceConstants.KIND_SERVICE, id)); } }); return result; } @Override public List<? extends Stack> getStacksThatMatch(Collection<String> currentIds) { return create().select(STACK.fields()) .from(STACK) .leftOuterJoin(SCHEDULED_UPGRADE) .on(SCHEDULED_UPGRADE.STACK_ID.eq(STACK.ID) .and(SCHEDULED_UPGRADE.REMOVED.isNull()) .and(SCHEDULED_UPGRADE.FINISHED.isNull())) .where(STACK.REMOVED.isNull() .and(STACK.SYSTEM.isTrue()) .and(STACK.EXTERNAL_ID.in(currentIds)) .and(SCHEDULED_UPGRADE.ID.isNull())) .fetchInto(StackRecord.class); } @Override public List<? extends Stack> getStacksToUpgrade(Collection<String> currentIds) { return create().select(STACK.fields()) .from(STACK) .leftOuterJoin(SCHEDULED_UPGRADE) .on(SCHEDULED_UPGRADE.STACK_ID.eq(STACK.ID) .and(SCHEDULED_UPGRADE.REMOVED.isNull()) .and(SCHEDULED_UPGRADE.FINISHED.isNull())) .where(STACK.REMOVED.isNull() .and(STACK.SYSTEM.isTrue()) .and(STACK.EXTERNAL_ID.notIn(currentIds)) .and(SCHEDULED_UPGRADE.ID.isNull())) .fetchInto(StackRecord.class); } @Override public List<? extends ScheduledUpgrade> getRunningUpgrades() { return create().select(SCHEDULED_UPGRADE.fields()) .from(SCHEDULED_UPGRADE) .where(SCHEDULED_UPGRADE.STATE.eq("running")) .fetchInto(ScheduledUpgradeRecord.class); } @Override public List<? extends ScheduledUpgrade> getReadyUpgrades(Set<Long> accountsToIgnore, int max) { Map<Long, ScheduledUpgrade> data = new HashMap<>(); create().select(SCHEDULED_UPGRADE.fields()) .from(SCHEDULED_UPGRADE) .join(STACK) .on(STACK.ID.eq(SCHEDULED_UPGRADE.STACK_ID) .and(STACK.REMOVE_TIME.isNotNull())) .where(SCHEDULED_UPGRADE.STATE.eq("scheduled")) .fetchInto(ScheduledUpgradeRecord.class) .forEach((x) -> { data.put(x.getId(), x); }); List<? extends ScheduledUpgrade> list = create().select(SCHEDULED_UPGRADE.fields()) .from(SCHEDULED_UPGRADE) .join(STACK) .on(STACK.ID.eq(SCHEDULED_UPGRADE.STACK_ID) .and(STACK.STATE.in(CommonStatesConstants.ACTIVE, ServiceConstants.STATE_UPGRADED))) .join(SERVICE) .on(SERVICE.STACK_ID.eq(STACK.ID).and(SERVICE.SKIP.isFalse())) .where(SCHEDULED_UPGRADE.STATE.eq("scheduled") .and(accountsToIgnore.size() == 0 ? DSL.trueCondition() : SCHEDULED_UPGRADE.ACCOUNT_ID.notIn(accountsToIgnore))) .orderBy(SCHEDULED_UPGRADE.PRIORITY.desc(), SCHEDULED_UPGRADE.CREATED.asc()) .limit(max * 4) .fetchInto(ScheduledUpgradeRecord.class); for (ScheduledUpgrade scheduledUpgrade : list) { if (data.size() >= max) { return new ArrayList<>(data.values()); } data.put(scheduledUpgrade.getId(), scheduledUpgrade); } return new ArrayList<>(data.values()); } }