package io.cattle.platform.configitem.server.impl; import io.cattle.platform.archaius.util.ArchaiusUtil; import io.cattle.platform.configitem.model.ItemVersion; import io.cattle.platform.configitem.registry.ConfigItemRegistry; import io.cattle.platform.configitem.request.ConfigUpdateRequest; import io.cattle.platform.configitem.server.model.ConfigItem; import io.cattle.platform.configitem.server.model.RefreshableConfigItem; import io.cattle.platform.configitem.server.model.Request; import io.cattle.platform.configitem.server.service.ConfigItemServer; import io.cattle.platform.configitem.version.ConfigItemStatusManager; import io.cattle.platform.lock.LockCallbackNoReturn; import io.cattle.platform.lock.LockManager; import io.cattle.platform.util.type.InitializationTask; import java.io.IOException; import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.netflix.config.DynamicStringListProperty; public class ConfigItemServerImpl implements ConfigItemServer, InitializationTask { private static final DynamicStringListProperty PRELOAD = ArchaiusUtil.getList("config.item.name.preload"); private static final Logger log = LoggerFactory.getLogger(ConfigItemServerImpl.class); ConfigItemStatusManager versionManager; ConfigItemRegistry itemRegistry; LockManager lockManager; @Override public void handleRequest(Request req) throws IOException { ItemVersion version = req.getAppliedVersion(); if (version == null) { handleDownload(req); } else { handleApplied(req); } } protected void handleApplied(Request req) { ItemVersion version = req.getAppliedVersion(); if (!versionManager.isAssigned(req.getClient(), req.getItemName())) { log.error("Client [{}] is reporting applied on non-assigned item [{}]", req.getClient(), req.getItemName()); req.setResponseCode(Request.NOT_FOUND); return; } ConfigItem item = itemRegistry.getConfigItem(req.getItemName()); if (version.isLatest()) { if (item == null) { req.setResponseCode(Request.NOT_FOUND); return; } log.info("Setting item [{}] to latest for [{}]", req.getItemName(), req.getClient()); versionManager.setLatest(req.getClient(), req.getItemName(), item.getSourceRevision()); } else { if (item.getSourceRevision().equals(version.getSourceRevision())) { log.info("Setting item [{}] to version [{}] for [{}]", req.getItemName(), req.getAppliedVersion(), req.getClient()); versionManager.setApplied(req.getClient(), req.getItemName(), req.getAppliedVersion()); } else { log.info("Ignoring item [{}] to version [{}] for [{}] because source revision [{}] does not match expect [{}]", req.getItemName(), req .getAppliedVersion(), req.getClient(), version.getSourceRevision(), item.getSourceRevision()); } } } protected void handleDownload(Request req) throws IOException { ConfigItem item = itemRegistry.getConfigItem(req.getItemName()); if (item == null) { log.info("Client [{}] requested unknown item [{}]", req.getClient(), req.getItemName()); req.setResponseCode(Request.NOT_FOUND); return; } if (!versionManager.isAssigned(req.getClient(), req.getItemName())) { if (item.isDynamicallyApplied()) { ConfigUpdateRequest updateRequest = new ConfigUpdateRequest(req.getClient()).withDeferredTrigger(true); updateRequest.addItem(req.getItemName()); versionManager.updateConfig(updateRequest); } else { log.error("Client [{}] requesting non-assigned item [{}]", req.getClient(), req.getItemName()); req.setResponseCode(Request.NOT_FOUND); return; } } log.info("Processing [{}] for client [{}]", req.getItemName(), req.getClient()); item.handleRequest(req); } @Override public void start() { syncSourceVersion(true); } @Override public void syncSourceVersion() { syncSourceVersion(false); } protected void syncSourceVersion(final boolean initial) { lockManager.lock(new SyncSourceVersionLock(), new LockCallbackNoReturn() { @Override public void doWithLockNoResult() { for (ConfigItem item : itemRegistry.getConfigItems()) { if (!initial) { if (item instanceof RefreshableConfigItem) { try { ((RefreshableConfigItem) item).refresh(); } catch (IOException e) { log.error("Failed to refresh item [{}]", item.getName(), e); continue; } } else { continue; } } versionManager.setItemSourceVersion(item.getName(), item.getSourceRevision()); } for (String item : PRELOAD.get()) { versionManager.setItemSourceVersion(item, ""); } } }); } public ConfigItemStatusManager getVersionManager() { return versionManager; } @Inject public void setVersionManager(ConfigItemStatusManager versionManager) { this.versionManager = versionManager; } public ConfigItemRegistry getItemRegistry() { return itemRegistry; } @Inject public void setItemRegistry(ConfigItemRegistry itemRegistry) { this.itemRegistry = itemRegistry; } public LockManager getLockManager() { return lockManager; } @Inject public void setLockManager(LockManager lockManager) { this.lockManager = lockManager; } }