/** * Updates the account for the given {@link Robot}. * * @param robot the {@link Robot} to update. * @throws CapabilityFetchException if the capabilities could not be fetched * or parsed. */ public void updateRobotAccount(Robot robot) throws CapabilityFetchException, PersistenceException { // TODO: Pass in activeAPIUrl String activeApiUrl = ""; RobotAccountData newAccount = connector.fetchCapabilities(robot.getAccount(), activeApiUrl); accountStore.putAccount(newAccount); robot.setAccount(newAccount); } }
/** * Updates a {@link Robot} with information about a waveletUpdate event. * * @param robot The robot to process the update for. * @param wavelet the wavelet on which the update is occuring. * @param deltas the deltas the have been applied to the given wavelet. */ private void updateRobot(Robot robot, ReadableWaveletData wavelet, DeltaSequence deltas) { try { robot.waveletUpdate(wavelet, deltas); ensureScheduled(robot); } catch (OperationException e) { LOG.warning("Unable to update robot(" + robot.getRobotName() + ")", e); } }
public void testProcessUpdatesAccountIfNoCapabilities() throws Exception { // Enqueue a wavelet so that the robot actually runs. enqueueEmptyWavelet(); robot.run(); assertEquals("The robot should be initialized", INITIALIZED_ACCOUNT, robot.getAccount()); }
public void testUpdateWaveletWithGap() throws Exception { HashedVersion hashedVersionZero = HASH_FACTORY.createVersionZero(WAVELET_NAME); WaveletData waveletData = WaveletDataUtil.createEmptyWavelet(WAVELET_NAME, ALEX, hashedVersionZero, 0L); robot.waveletUpdate(waveletData, DeltaSequence.empty()); // We are making an delta which applies to version 1, however the robot only // knows about version 0. ParticipantId bob = ParticipantId.of("bob@exmaple.com"); HashedVersion v2 = HashedVersion.unsigned(2); WaveletOperation addBob = new AddParticipant(new WaveletOperationContext(ALEX, 0L, 1, v2), bob); addBob.apply(waveletData); waveletData.setHashedVersion(v2); waveletData.setVersion(2); TransformedWaveletDelta delta = new TransformedWaveletDelta(ALEX, v2, 0L, Collections.singletonList(addBob)); // Send the delta for version 1 to the robot, it should now enqueue a new // wavelet since it is missing deltas. robot.waveletUpdate(waveletData, DeltaSequence.of(delta)); WaveletAndDeltas firstWavelet = robot.dequeueWavelet(); assertNotNull("Expected a wavelet to be dequeued", firstWavelet); assertEquals("The wavelet with version zero should be first", hashedVersionZero, firstWavelet.getVersionAfterDeltas()); WaveletAndDeltas secondWavelet = robot.dequeueWavelet(); assertNotNull("Expected a wavelet to be dequeued", secondWavelet); assertEquals("The wavelet with version two should be second", v2, secondWavelet.getVersionAfterDeltas()); assertNull("Only expected two wavelets to be dequeued", robot.dequeueWavelet()); }
public void testEnsureRunnableCallsRobot() throws Exception { Robot robot = mock(Robot.class); when(robot.getRobotName()).thenReturn(RobotName.fromAddress("robot@example.com")); gateway.ensureScheduled(robot); executor.runAllCommands(); verify(robot).run(); }
@Override protected void setUp() throws Exception { connection = mock(RobotConnection.class); serializer = mock(RobotSerializer.class); connector = new RobotConnector(connection, serializer); robot = mock(Robot.class); when(robot.getAccount()).thenReturn(ROBOT_ACCOUNT); }
public void testDequeueWaveletReturnsNullIfEmpty() throws Exception { assertNull("On empty queue should return null", robot.dequeueWavelet()); }
public void testRunNotRequeingIfNoWork() { robot.run(); verify(gateway).doneRunning(robot); verify(gateway, never()).ensureScheduled(robot); }
@Override public Object answer(InvocationOnMock invocation) throws Throwable { robot.setAccount(INITIALIZED_ACCOUNT); return null; } }).when(gateway).updateRobotAccount(robot);
/** * Creates a new {@link Robot}. * * @param robotName the name of the robot. * @param account the {@link RobotAccountData} belonging to the given * {@link RobotName}. */ private Robot createNewRobot(RobotName robotName, RobotAccountData account) { EventGenerator eventGenerator = new EventGenerator(robotName, conversationUtil); RobotOperationApplicator operationApplicator = new RobotOperationApplicator(converterManager, waveletProvider, new OperationServiceRegistryImpl(notifyOpService), conversationUtil); return new Robot(robotName, account, this, connector, converterManager, waveletProvider, eventGenerator, operationApplicator); }
/** * Runs this {@link Robot} by checking its queue for a new wavelet and then * processing this wavelet. In the end the {@link Robot} will check whether it * needs to requeue itself in the RobotGateway or that no further actions need * to be taken. */ @Override public void run() { try { LOG.fine(robotName + " called for processing"); WaveletAndDeltas wavelet = dequeueWavelet(); if (wavelet == null) { gateway.doneRunning(this); return; } process(wavelet); } catch (RuntimeException e) { LOG.severe("Unexpected error occurred when robot " + robotName + " was called", e); } // Requeue since we either had an exception or we processed a wavelet. gateway.doneRunning(this); gateway.ensureScheduled(this); }
/** * Enqueues an empty wavelet into the {@link Robot}. */ private void enqueueEmptyWavelet() throws Exception { HashedVersion hashedVersionZero = HASH_FACTORY.createVersionZero(WAVELET_NAME); WaveletData waveletData = WaveletDataUtil.createEmptyWavelet(WAVELET_NAME, ALEX, hashedVersionZero, 0L); robot.waveletUpdate(waveletData, DeltaSequence.empty()); } }
/** * Signal that a robot is done running. Synchronized with ensureRunnable since * that method needs to have a synchronized view on the runnableRobots for * submitting task to the executor. * * @param robot the {@link Robot} which is done working. */ public synchronized void doneRunning(Robot robot) { runnableRobots.remove(robot.getRobotName()); }
public void testUpdateWaveletWithGap() throws Exception { HashedVersion hashedVersionZero = HASH_FACTORY.createVersionZero(WAVELET_NAME); WaveletData waveletData = WaveletDataUtil.createEmptyWavelet(WAVELET_NAME, ALEX, hashedVersionZero, 0L); robot.waveletUpdate(waveletData, DeltaSequence.empty()); // We are making an delta which applies to version 1, however the robot only // knows about version 0. ParticipantId bob = ParticipantId.of("bob@exmaple.com"); HashedVersion v2 = HashedVersion.unsigned(2); WaveletOperation addBob = new AddParticipant(new WaveletOperationContext(ALEX, 0L, 1, v2), bob); addBob.apply(waveletData); waveletData.setHashedVersion(v2); waveletData.setVersion(2); TransformedWaveletDelta delta = new TransformedWaveletDelta(ALEX, v2, 0L, Collections.singletonList(addBob)); // Send the delta for version 1 to the robot, it should now enqueue a new // wavelet since it is missing deltas. robot.waveletUpdate(waveletData, DeltaSequence.of(delta)); WaveletAndDeltas firstWavelet = robot.dequeueWavelet(); assertNotNull("Expected a wavelet to be dequeued", firstWavelet); assertEquals("The wavelet with version zero should be first", hashedVersionZero, firstWavelet.getVersionAfterDeltas()); WaveletAndDeltas secondWavelet = robot.dequeueWavelet(); assertNotNull("Expected a wavelet to be dequeued", secondWavelet); assertEquals("The wavelet with version two should be second", v2, secondWavelet.getVersionAfterDeltas()); assertNull("Only expected two wavelets to be dequeued", robot.dequeueWavelet()); }
public void testEnsureRunnableCallsRobot() throws Exception { Robot robot = mock(Robot.class); when(robot.getRobotName()).thenReturn(RobotName.fromAddress("robot@example.com")); gateway.ensureScheduled(robot); executor.runAllCommands(); verify(robot).run(); }
@Override protected void setUp() throws Exception { connection = mock(RobotConnection.class); serializer = mock(RobotSerializer.class); connector = new RobotConnector(connection, serializer); robot = mock(Robot.class); when(robot.getAccount()).thenReturn(ROBOT_ACCOUNT); }
public void testDequeueWaveletReturnsNullIfEmpty() throws Exception { assertNull("On empty queue should return null", robot.dequeueWavelet()); }
public void testRunNotRequeingIfNoWork() { robot.run(); verify(gateway).doneRunning(robot); verify(gateway, never()).ensureScheduled(robot); }
@Override public Object answer(InvocationOnMock invocation) throws Throwable { robot.setAccount(INITIALIZED_ACCOUNT); return null; } }).when(gateway).updateRobotAccount(robot);
@SuppressWarnings("unchecked") @Override protected void setUp() throws Exception { gateway = mock(RobotsGateway.class); connector = mock(RobotConnector.class); converterManager = mock(EventDataConverterManager.class); waveletProvider = mock(WaveletProvider.class); eventGenerator = mock(EventGenerator.class); operationApplicator = mock(RobotOperationApplicator.class); robot = new Robot(ROBOT_NAME, ACCOUNT, gateway, connector, converterManager, waveletProvider, eventGenerator, operationApplicator); // Set the initialized account when updateRobotAccount is called. doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { robot.setAccount(INITIALIZED_ACCOUNT); return null; } }).when(gateway).updateRobotAccount(robot); // Generate no events on default EventMessageBundle emptyMessageBundle = new EventMessageBundle(ROBOT_NAME.toEmailAddress(), ""); when(eventGenerator.generateEvents( any(WaveletAndDeltas.class), anyMap(), any(EventDataConverter.class))).thenReturn( emptyMessageBundle); }