package org.dcache.services.info.gathers.domain; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dmg.cells.nucleus.UOID; import org.dcache.services.info.base.StatePath; import org.dcache.services.info.base.StateUpdate; import org.dcache.services.info.base.StateUpdateManager; import org.dcache.services.info.base.StateValue; import org.dcache.services.info.base.StringStateValue; import org.dcache.services.info.gathers.CellMessageHandlerSkel; import org.dcache.services.info.gathers.MessageMetadataRepository; import static com.google.common.base.Preconditions.checkArgument; /** * This class handles reply messages from the ASCII command * "show context info.static". The value is parsed and dCache's state is * updated accordingly. */ public class StaticDomainMsgHandler extends CellMessageHandlerSkel { private static final Logger LOGGER = LoggerFactory.getLogger(StaticDomainMsgHandler.class); private static final StatePath DOMAINS = StatePath.parsePath("domains"); public StaticDomainMsgHandler(StateUpdateManager sum, MessageMetadataRepository<UOID> msgMetaRepo) { super(sum, msgMetaRepo); } @Override public void process(Object payload, long lifetime) { if (payload == null) { LOGGER.error("received null payload"); return; } if (!(payload instanceof String)) { LOGGER.error("received message of type {}", payload.getClass().getCanonicalName()); return; } String declaration = (String) payload; StatePath parent = metricsParent(); StateUpdate update = processDeclaration(parent, lifetime, declaration); applyUpdates(update); } private StatePath metricsParent() { return DOMAINS.newChild(getDomain()).newChild("static"); } private StateUpdate processDeclaration(StatePath parent, long lifetime, String declaration) { StateUpdate update = new StateUpdate(); update.purgeUnder(parent); for (String rawLine : declaration.split("\n")) { String line = rawLine.trim(); if (line.isEmpty()) { continue; } try { processLine(update, lifetime, parent, line); } catch (IllegalArgumentException e) { LOGGER.error(e.getMessage()); } } return update; } /** * Process a line of the format {@literal <type><sep><name><sep><data>} * where {@literal <type>} and {@literal <sep>} are single characters. */ private void processLine(StateUpdate update, long lifetime, StatePath parent, String line) { checkArgument(line.length() >= 5, "Line too short: " + line); char type = line.charAt(0); char seperator = line.charAt(1); int idx = line.indexOf(seperator, 3); checkArgument(idx != -1, "Seperator character '" + seperator + "' missing"); checkArgument(idx != line.length()-1, "Metric has no data"); String value = line.substring(idx+1); StateValue metric = metricFor(type, value, lifetime); String name = line.substring(2, idx); StatePath relativePath = StatePath.parsePath(name); StatePath path = parent.newChild(relativePath); update.appendUpdate(path, metric); } private static StateValue metricFor(char type, String value, long lifetime) { switch(type) { case 'S': return new StringStateValue(value, lifetime); default: throw new IllegalArgumentException("Unknown type: " + type); } } }