package org.dcache.tests.cells; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; import diskCacheV111.vehicles.Message; import dmg.cells.nucleus.CellAddressCore; import dmg.cells.nucleus.CellEndpoint; import dmg.cells.nucleus.CellInfo; import dmg.cells.nucleus.CellMessage; import dmg.cells.nucleus.CellMessageAnswerable; import dmg.cells.nucleus.CellPath; import dmg.cells.nucleus.SerializationException; import static java.util.Arrays.asList; public class MockCellEndpoint implements CellEndpoint { private final Map<CellPath, Map<String, List<MessageEnvelope>>> messageQueue = new HashMap<>(); private final Map<String, Map<Class<?>, MessageAction>> messageActions = new HashMap<>(); private final CellInfo info; private final CellAddressCore address; public MockCellEndpoint(String name) { address = new CellAddressCore(name); info = new CellInfo(); info.setCellName(name); info.setDomainName("mockDomain"); info.setCellType("generic"); info.setCreationTime(new Date()); } /** * * same as <i>prepareMessage( cellPath, message, false);</i> * * @param cellPath * @param message */ public void prepareMessage(CellPath cellPath, Message message) { prepareMessage(cellPath, message, false); } /** * create pre-defined reply from a cell. * * @param cellPath * @param message * @param isPersistent remove message from reply list if false */ public void prepareMessage(CellPath cellPath, Message message, boolean isPersistent) { Map<String, List<MessageEnvelope>> messagesByType = messageQueue.get(cellPath); if (messagesByType == null) { messagesByType = new HashMap<>(); messageQueue.put(cellPath, messagesByType); } String messageType = message.getClass().getName(); List<MessageEnvelope> messages = messagesByType.get(messageType); if (messages == null) { messages = new ArrayList<>(); messagesByType.put(messageType, messages); } messages.add(new MessageEnvelope(message, isPersistent)); } public void registerAction(String cellName, Class<?> messageClass, MessageAction action) { Map<Class<?>, MessageAction> actions = messageActions.get(cellName); if (actions == null) { actions = new HashMap<>(); messageActions.put(cellName, actions); } actions.put(messageClass, action); } @Override public void sendMessage(CellMessage envelope, CellMessageAnswerable callback, Executor executor, long timeout, SendFlag... flags) throws SerializationException { if (!asList(flags).contains(SendFlag.PASS_THROUGH)) { envelope.addSourceAddress(address); } Map<String, List<MessageEnvelope>> messages = messageQueue.get(envelope.getDestinationPath()); List<MessageEnvelope> envelopes = messages.get(envelope.getMessageObject().getClass().getName()); MessageEnvelope m = envelopes.get(0); if(!m.isPersistent()) { envelopes.remove(0); } callback.answerArrived(envelope, new CellMessage(envelope.getDestinationPath(), m.getMessage())); } @Override public void sendMessage(CellMessage envelope, SendFlag... flags) { if (!asList(flags).contains(SendFlag.PASS_THROUGH)) { envelope.addSourceAddress(address); } String destinations = envelope.getDestinationPath().getCellName(); Map<Class<?>, MessageAction> actions = messageActions.get(destinations); if (actions != null) { // there is something pre-defined MessageAction action = actions.get(envelope.getMessageObject().getClass()); if (action != null) { envelope.revertDirection(); action.messageArrived(envelope); } } } @Override public Map<String, Object> getDomainContext() { return Collections.emptyMap(); } public interface MessageAction { void messageArrived(CellMessage message); } private static class MessageEnvelope { private final Message message; private final boolean isPersistent; MessageEnvelope(Message message, boolean isPersistent) { this.message = message; this.isPersistent = isPersistent; } Message getMessage() { return message; } boolean isPersistent() { return isPersistent; } } }