package io.cattle.platform.core.dao.impl; import static io.cattle.platform.core.model.tables.AgentTable.*; import static io.cattle.platform.core.model.tables.HostTable.*; import static io.cattle.platform.core.model.tables.InstanceHostMapTable.*; import static io.cattle.platform.core.model.tables.InstanceTable.*; import static io.cattle.platform.core.model.tables.PhysicalHostTable.*; import static io.cattle.platform.core.model.tables.StoragePoolTable.*; import io.cattle.platform.core.constants.AgentConstants; import io.cattle.platform.core.constants.CommonStatesConstants; import io.cattle.platform.core.constants.HostConstants; import io.cattle.platform.core.constants.InstanceConstants; import io.cattle.platform.core.dao.AgentDao; import io.cattle.platform.core.dao.HostDao; import io.cattle.platform.core.model.Agent; import io.cattle.platform.core.model.Host; import io.cattle.platform.core.model.Instance; import io.cattle.platform.core.model.PhysicalHost; import io.cattle.platform.core.model.StoragePool; import io.cattle.platform.core.model.tables.records.AgentRecord; import io.cattle.platform.core.model.tables.records.HostRecord; import io.cattle.platform.core.model.tables.records.PhysicalHostRecord; import io.cattle.platform.core.model.tables.records.StoragePoolRecord; import io.cattle.platform.object.util.DataAccessor; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Named; import org.apache.commons.lang3.StringUtils; import org.jooq.Record; import org.jooq.Record1; @Named public class AgentDaoImpl extends AbstractCoreDao implements AgentDao { Long startTime = null; @Override public Agent findNonRemovedByUri(String uri) { return create() .selectFrom(AGENT) .where( AGENT.URI.eq(uri) .and(AGENT.REMOVED.isNull())) .fetchOne(); } @Override public Map<String, Host> getHosts(long agentId) { List<? extends Host> hostList = create() .select(HOST.fields()) .from(HOST) .where( HOST.AGENT_ID.eq(agentId) .and(HOST.REMOVED.isNull())) .fetchInto(HostRecord.class); return groupByReportedUUid(hostList); } public Map<String, Host> groupByReportedUUid(List<? extends Host> hostList) { Map<String,Host> hosts = new HashMap<>(); for ( Host host : hostList ) { String uuid = DataAccessor.fields(host).withKey(HostConstants.FIELD_REPORTED_UUID).as(String.class); if ( uuid == null ) { uuid = host.getUuid(); } hosts.put(uuid, host); } return hosts; } @Override public Map<String, StoragePool> getStoragePools(long agentId) { Map<String,StoragePool> pools = new HashMap<>(); List<? extends StoragePool> poolList = create() .select(STORAGE_POOL.fields()) .from(STORAGE_POOL) .where( STORAGE_POOL.AGENT_ID.eq(agentId) .and(STORAGE_POOL.REMOVED.isNull())) .fetchInto(StoragePoolRecord.class); for ( StoragePool pool : poolList ) { String uuid = DataAccessor.fields(pool).withKey(HostConstants.FIELD_REPORTED_UUID).as(String.class); if ( uuid == null ) { uuid = pool.getUuid(); } pools.put(uuid, pool); } return pools; } @Override public Map<String, PhysicalHost> getPhysicalHosts(long agentId) { Map<String,PhysicalHost> hosts = new HashMap<>(); List<? extends PhysicalHost> hostList = create() .select(PHYSICAL_HOST.fields()) .from(PHYSICAL_HOST) .where( PHYSICAL_HOST.AGENT_ID.eq(agentId) .and(PHYSICAL_HOST.REMOVED.isNull())) .fetchInto(PhysicalHostRecord.class); for ( PhysicalHost host : hostList ) { String uuid = host.getExternalId(); if (StringUtils.isEmpty(uuid)) { uuid = DataAccessor.fields(host).withKey(HostConstants.FIELD_REPORTED_UUID).as(String.class); } if (StringUtils.isEmpty(uuid)) { uuid = host.getUuid(); } hosts.put(uuid, host); } return hosts; } @Override public Agent getHostAgentForDelegate(long agentId) { List<? extends Agent> result = create().select(AGENT.fields()) .from(AGENT) .join(HOST) .on(HOST.AGENT_ID.eq(AGENT.ID)) .join(INSTANCE_HOST_MAP) .on(INSTANCE_HOST_MAP.HOST_ID.eq(HOST.ID)) .join(INSTANCE) .on(INSTANCE_HOST_MAP.INSTANCE_ID.eq(INSTANCE.ID)) .where(INSTANCE.AGENT_ID.eq(agentId)).fetchInto(AgentRecord.class); return result.size() == 0 ? null : result.get(0); } @Override public Host getHost(Agent agent) { Record record = create() .select(HOST.fields()) .from(INSTANCE) .join(INSTANCE_HOST_MAP) .on(INSTANCE_HOST_MAP.INSTANCE_ID.eq(INSTANCE.ID) .and(INSTANCE_HOST_MAP.REMOVED.isNull())) .join(HOST) .on(INSTANCE_HOST_MAP.HOST_ID.eq(HOST.ID)) .where(INSTANCE.AGENT_ID.eq(agent.getId()) .and(INSTANCE.REMOVED.isNull().and( INSTANCE.STATE.notIn(InstanceConstants.STATE_ERROR, InstanceConstants.STATE_ERRORING, CommonStatesConstants.REMOVING))) .and(HOST.REMOVED.isNull())) .fetchAny(); return record == null ? null : record.into(Host.class); } @Override public Instance getInstance(Agent agent) { return create() .selectFrom(INSTANCE) .where(INSTANCE.AGENT_ID.eq(agent.getId()) .and(INSTANCE.REMOVED.isNull()) .and(INSTANCE.STATE.notIn(InstanceConstants.STATE_ERROR, InstanceConstants.STATE_ERRORING, CommonStatesConstants.REMOVING))) .fetchOne(); } @Override public String getAgentState(long agentId) { Record1<String> r = create().select(AGENT.STATE) .from(AGENT) .where(AGENT.ID.eq(agentId) .and(AGENT.REMOVED.isNull())).fetchAny(); return r == null ? null : r.value1(); } @Override public List<? extends Agent> findAgentsToRemove() { if (startTime == null) { startTime = System.currentTimeMillis(); } if ((System.currentTimeMillis() - startTime) <= (HostDao.HOST_REMOVE_START_DELAY.get() * 1000)) { return Collections.emptyList(); } List<? extends Agent> agents = create().select(AGENT.fields()) .from(AGENT) .leftOuterJoin(HOST) .on(HOST.AGENT_ID.eq(AGENT.ID)) .where(HOST.ID.isNull().or(HOST.REMOVED.isNotNull()) .and(AGENT.STATE.eq(AgentConstants.STATE_DISCONNECTED))) .fetchInto(AgentRecord.class); // This is purging old pre-1.2 agent delegates List<? extends Agent> oldAgents = create().select(AGENT.fields()) .from(AGENT) .where(AGENT.REMOVED.isNull().and(AGENT.URI.like("delegate%"))) .fetchInto(AgentRecord.class); List<Agent> result = new ArrayList<>(agents); result.addAll(oldAgents); return result; } }