/** * Executes an {@link OperationRequest}. If the operation throws an * {@link InvalidRequestException} this exception will be used to construct an * error response in the {@link OperationContext}. * * @param operation the operation to be executed. If the operation contains * {@link ParamsProperty.PROXYING_FOR} - then it will be taken in * account. * @param operationRegistry the registry containing the operations that can be * performed. * @param context the context in which the operation is to be executed. * @param author the author of the operation. */ public static void executeOperation(OperationRequest operation, OperationServiceRegistry operationRegistry, OperationContext context, ParticipantId author) { try { OperationService service = operationRegistry.getServiceFor(OperationUtil.getOperationType(operation)); ParticipantId proxyParticipant = OperationUtil.computeParticipant(operation, author); service.execute(operation, context, proxyParticipant); } catch (InvalidRequestException e) { LOG.warning("Operation " + operation + " failed to execute", e); context.constructErrorResponse(operation, e.getMessage()); } }
/** * Executes operations in the given context. * * @param context the context to perform the operations in. * @param operations the operations to perform. * @param author the author for which to perform the robot operations. */ private void executeOperations( OperationContext context, List<OperationRequest> operations, ParticipantId author) { for (OperationRequest operation : operations) { OperationUtil.executeOperation(operation, operationRegistry, context, author); } }
@Override public void execute(OperationRequest operation, OperationContext context, ParticipantId participant) throws InvalidRequestException { String modifyHow = OperationUtil.getRequiredParameter(operation, ParamsProperty.MODIFY_HOW); String blipId = OperationUtil.getOptionalParameter(operation, ParamsProperty.BLIP_ID); SupplementedWave supplement = buildSupplement(operation, context, participant); if (modifyHow.equals(ModifyHowType.MARK_AS_READ.getValue())) { if (blipId == null || blipId.isEmpty()) { supplement.markAsRead(); } else { ObservableConversation conversation = context.openConversation(operation, participant).getRoot(); ConversationBlip blip = conversation.getBlip(blipId); supplement.markAsRead(blip); } } else if (modifyHow.equals(ModifyHowType.MARK_AS_UNREAD.getValue())) { supplement.markAsUnread(); } else { throw new UnsupportedOperationException("Unsupported folder action: " + modifyHow); } // Construct empty response. Map<ParamsProperty, Object> data = Maps.newHashMap(); context.constructResponse(operation, data); } }
@Override public void execute( OperationRequest operation, OperationContext context, ParticipantId participant) throws InvalidRequestException { String query = OperationUtil.getRequiredParameter(operation, ParamsProperty.QUERY); int index = OperationUtil.getOptionalParameter(operation, ParamsProperty.INDEX, 0); int numResults = OperationUtil.getOptionalParameter( operation, ParamsProperty.NUM_RESULTS, DEFAULT_NUMBER_SEARCH_RESULTS); SearchResult result = search(participant, query, index, numResults); Map<ParamsProperty, Object> data = ImmutableMap.<ParamsProperty, Object> of(ParamsProperty.SEARCH_RESULTS, result); context.constructResponse(operation, data); }
/** * Computes participant ID using optional {@link ParamsProperty.PROXYING_FOR} * parameter. * * @param operation the operation to be executed. * @param participant the base participant id. * @return new participant instance in the format * somebody+proxyFor@example.com. If proxyFor is null then just * returns unmodified participant. * @throws InvalidRequestException if participant address and/or proxyFor are * invalid. */ public static ParticipantId computeParticipant(OperationRequest operation, ParticipantId participant) throws InvalidRequestException { String proxyAddress = OperationUtil.getOptionalParameter(operation, ParamsProperty.PROXYING_FOR); try { return toProxyParticipant(participant, proxyAddress); } catch (InvalidParticipantAddress e) { throw new InvalidRequestException( participant.getAddress() + (proxyAddress != null ? "+" + proxyAddress : "" + " is not a valid participant address"), operation); } }
/** * Implementation for the {@link OperationType#BLIP_DELETE} method. It deletes * the blip specified in the operation. * * @param operation the operation to execute. * @param context the context of the operation. * @param participant the participant performing this operation. * @param conversation the conversation to operate on. * @throws InvalidRequestException if the operation fails to perform */ private void delete(OperationRequest operation, OperationContext context, ParticipantId participant, ObservableConversation conversation) throws InvalidRequestException { Preconditions.checkArgument( OperationUtil.getOperationType(operation) == OperationType.BLIP_DELETE, "Unsupported operation " + operation); String blipId = OperationUtil.getRequiredParameter(operation, ParamsProperty.BLIP_ID); context.getBlip(conversation, blipId).delete(); // report success. context.constructResponse(operation, Maps.<ParamsProperty, Object> newHashMap()); }
@Override public void execute(OperationRequest operation, OperationContext context, ParticipantId participant) throws InvalidRequestException { FetchProfilesRequest request = OperationUtil.getRequiredParameter(operation, ParamsProperty.FETCH_PROFILES_REQUEST); List<String> requestAddresses = request.getParticipantIds(); List<ParticipantProfile> profiles = Lists.newArrayListWithCapacity(requestAddresses.size()); for (String address : requestAddresses) { ParticipantProfile participantProfile = profilesFetcher.fetchProfile(address); profiles.add(participantProfile); } FetchProfilesResult result = new FetchProfilesResult(profiles); Map<ParamsProperty, Object> data = ImmutableMap.<ParamsProperty, Object> of(ParamsProperty.FETCH_PROFILES_RESULT, result); context.constructResponse(operation, data); } }
/** * Attempts to get a parameter, returns the {@code null} if not found. * * @param <T> type of class to cast to. * @param operation operation to extract property from. * @param key the key of the parameter. * @return specialized object after being serialized, or {@code null} if the * parameter could not be found. */ public static <T> T getOptionalParameter(OperationRequest operation, ParamsProperty key) { return OperationUtil.<T> getOptionalParameter(operation, key, null); }
public void testComputeParticipantWithInvalidProxyFor() throws Exception { String invalidProxyFor = "~@#+^+"; String participantAddress = "foo@bar.com"; OperationRequest operation = mock(OperationRequest.class); when(operation.getParameter(ParamsProperty.PROXYING_FOR)).thenReturn(invalidProxyFor); try { OperationUtil.computeParticipant(operation, ParticipantId.of(participantAddress)); fail("InvalidRequestException should be thrown."); } catch (InvalidRequestException e) { // Pass. } verify(operation).getParameter(ParamsProperty.PROXYING_FOR); }
/** * Handles an {@link OperationResults} by submitting the deltas it generates * and sending off any events to the robot. Note that currently no events are * send off to the robot. * * @param results the results of the operations performed * @param account the account for which to handle results of robot operations. */ private void handleResults(OperationResults results, RobotAccountData account) { OperationUtil.submitDeltas(results, waveletProvider, LOGGING_REQUEST_LISTENER); // TODO(ljvderijk): In theory we should be sending off all events that are // generated by the operations. Currently not done in production. We should // make it possible though. boolean notifyOnError = account.getCapabilities().getCapabilitiesMap().containsKey(EventType.OPERATION_ERROR); } }
public void testGetProtocolVersion() throws Exception { ProtocolVersion protocolVersion = OperationUtil.getProtocolVersion(Collections.<OperationRequest> emptyList()); assertEquals( "Empty list should return default version", ProtocolVersion.DEFAULT, protocolVersion); protocolVersion = OperationUtil.getProtocolVersion(Collections.singletonList(operation)); assertEquals("Non notify op as first op should return default", ProtocolVersion.DEFAULT, protocolVersion); OperationRequest notifyOp = new OperationRequest(OperationType.ROBOT_NOTIFY.method(), "op1"); protocolVersion = OperationUtil.getProtocolVersion(Collections.singletonList(notifyOp)); assertEquals("Notify op as first op without version parameter should return default", ProtocolVersion.DEFAULT, protocolVersion); Parameter versionParameter = Parameter.of(ParamsProperty.PROTOCOL_VERSION, ProtocolVersion.V2_1.getVersionString()); notifyOp = new OperationRequest(OperationType.ROBOT_NOTIFY.method(), "op1", versionParameter); protocolVersion = OperationUtil.getProtocolVersion(Collections.singletonList(notifyOp)); assertEquals( "Notify op as first op should return its version", ProtocolVersion.V2_1, protocolVersion); }
public void testToProxyParticipant() throws Exception { ParticipantId participant = ParticipantId.of("foo@example.com"); ParticipantId proxyParticipant = ParticipantId.of("foo+proxyFor@example.com"); assertEquals(proxyParticipant, OperationUtil.toProxyParticipant(participant, "proxyFor")); // If participant is already a proxy - return without a change. assertEquals(proxyParticipant, OperationUtil.toProxyParticipant(proxyParticipant, "proxyFor")); }
public void testGetRequiredParameterThrowsInvalidRequestException() throws Exception { try { OperationUtil.getRequiredParameter(operation, ParamsProperty.ANNOTATION); fail("Expected InvalidRequestException"); } catch (InvalidRequestException e) { // expected } }
/** * Implementation for the {@link OperationType#DOCUMENT_APPEND_MARKUP} * method. It appends markup within the blip specified in * the operation. * * @param operation the operation to execute. * @param context the context of the operation. * @param participant the participant performing this operation. * @param wavelet the wavelet to operate on. * @param conversation the conversation to operate on. * @throws InvalidRequestException if the operation fails to perform */ private void appendMarkup(OperationRequest operation, OperationContext context, ParticipantId participant, ObservableWavelet wavelet, ObservableConversation conversation) throws InvalidRequestException { Preconditions.checkArgument( OperationUtil.getOperationType(operation) == OperationType.DOCUMENT_APPEND_MARKUP, "Unsupported operation " + operation); String content = OperationUtil.getRequiredParameter(operation, ParamsProperty.CONTENT); String blipId = OperationUtil.getRequiredParameter(operation, ParamsProperty.BLIP_ID); ConversationBlip convBlip = context.getBlip(conversation, blipId); // Create builder from xml content. XmlStringBuilder markupBuilder = XmlStringBuilder.createFromXmlString(content); // Append the new markup to the blip doc. Document doc = convBlip.getContent(); LineContainers.appendLine(doc, markupBuilder); // Report success. context.constructResponse(operation, Maps.<ParamsProperty, Object> newHashMap()); }
throws InvalidRequestException { WaveletData waveletData = OperationUtil.getRequiredParameter(operation, ParamsProperty.WAVELET_DATA); String message = OperationUtil.getOptionalParameter(operation, ParamsProperty.MESSAGE); WaveletCreatedEvent event = new WaveletCreatedEvent(null, null, participant.getAddress(), System.currentTimeMillis(),
public void testGetOptionalParameter() throws Exception { String waveId = OperationUtil.getOptionalParameter(operation, ParamsProperty.WAVE_ID); assertEquals(s(WAVE_ID), waveId); assertNull("Non existing properties should return null when optional", OperationUtil.getOptionalParameter(operation, ParamsProperty.ANNOTATION)); String defaultValue = "b+1234"; String blipId = OperationUtil.getOptionalParameter(operation, ParamsProperty.BLIP_ID, defaultValue); assertSame("Default value should be returned when object does not exist", defaultValue, blipId); }
public void testComputeParticipantWithValidProxyFor() throws Exception { String validProxyFor = "foo"; String participantAddress = "foo@bar.com"; OperationRequest operation = mock(OperationRequest.class); when(operation.getParameter(ParamsProperty.PROXYING_FOR)).thenReturn(validProxyFor); try { OperationUtil.computeParticipant(operation, ParticipantId.of(participantAddress)); } catch (InvalidRequestException e) { fail("Exception is thrown for a valid address."); } verify(operation).getParameter(ParamsProperty.PROXYING_FOR); } }
OperationResults results, HttpServletResponse resp, ProtocolVersion version) throws IOException { OperationUtil.submitDeltas(results, waveletProvider, LOGGING_REQUEST_LISTENER);
public void testGetProtocolVersion() throws Exception { ProtocolVersion protocolVersion = OperationUtil.getProtocolVersion(Collections.<OperationRequest> emptyList()); assertEquals( "Empty list should return default version", ProtocolVersion.DEFAULT, protocolVersion); protocolVersion = OperationUtil.getProtocolVersion(Collections.singletonList(operation)); assertEquals("Non notify op as first op should return default", ProtocolVersion.DEFAULT, protocolVersion); OperationRequest notifyOp = new OperationRequest(OperationType.ROBOT_NOTIFY.method(), "op1"); protocolVersion = OperationUtil.getProtocolVersion(Collections.singletonList(notifyOp)); assertEquals("Notify op as first op without version parameter should return default", ProtocolVersion.DEFAULT, protocolVersion); Parameter versionParameter = Parameter.of(ParamsProperty.PROTOCOL_VERSION, ProtocolVersion.V2_1.getVersionString()); notifyOp = new OperationRequest(OperationType.ROBOT_NOTIFY.method(), "op1", versionParameter); protocolVersion = OperationUtil.getProtocolVersion(Collections.singletonList(notifyOp)); assertEquals( "Notify op as first op should return its version", ProtocolVersion.V2_1, protocolVersion); }
public void testToProxyParticipant() throws Exception { ParticipantId participant = ParticipantId.of("foo@example.com"); ParticipantId proxyParticipant = ParticipantId.of("foo+proxyFor@example.com"); assertEquals(proxyParticipant, OperationUtil.toProxyParticipant(participant, "proxyFor")); // If participant is already a proxy - return without a change. assertEquals(proxyParticipant, OperationUtil.toProxyParticipant(proxyParticipant, "proxyFor")); }