use of io.vertx.proton.ProtonReceiver in project hono by eclipse.
the class HonoClientUnitTestHelper method mockProtonReceiver.
/**
* Creates a mocked Proton receiver which always returns {@code true} when its isOpen method is called.
*
* @return The mocked receiver.
*/
public static final ProtonReceiver mockProtonReceiver() {
final ProtonReceiver receiver = mock(ProtonReceiver.class);
when(receiver.isOpen()).thenReturn(Boolean.TRUE);
return receiver;
}
use of io.vertx.proton.ProtonReceiver in project hono by eclipse.
the class RegistrationClientImplTest method setUp.
/**
* Sets up the fixture.
*/
@SuppressWarnings("unchecked")
@Before
public void setUp() {
vertx = mock(Vertx.class);
context = HonoClientUnitTestHelper.mockContext(vertx);
final ProtonReceiver receiver = HonoClientUnitTestHelper.mockProtonReceiver();
sender = HonoClientUnitTestHelper.mockProtonSender();
cache = mock(ExpiringValueCache.class);
final RequestResponseClientConfigProperties config = new RequestResponseClientConfigProperties();
client = new RegistrationClientImpl(context, config, "tenant", sender, receiver);
}
use of io.vertx.proton.ProtonReceiver in project hono by eclipse.
the class RequestResponseEndpoint method handleMessage.
/**
* Handles a request message received from a client.
* <p>
* The message gets rejected if
* <ul>
* <li>the message does not pass {@linkplain #passesFormalVerification(ResourceIdentifier, Message) formal verification}
* or</li>
* <li>the client is not {@linkplain #isAuthorized(HonoUser, ResourceIdentifier, Message) authorized to execute the operation}
* indicated by the message's <em>subject</em> or</li>
* <li>its payload cannot be parsed</li>
* </ul>
*
* @param con The connection with the client.
* @param receiver The link over which the message has been received.
* @param targetAddress The address the message is sent to.
* @param delivery The message's delivery status.
* @param message The message.
*/
protected final void handleMessage(final ProtonConnection con, final ProtonReceiver receiver, final ResourceIdentifier targetAddress, ProtonDelivery delivery, Message message) {
final Future<Void> formalCheck = Future.future();
if (passesFormalVerification(targetAddress, message)) {
formalCheck.complete();
} else {
formalCheck.fail(new AmqpErrorException(AmqpError.DECODE_ERROR, "malformed payload"));
}
final HonoUser clientPrincipal = Constants.getClientPrincipal(con);
formalCheck.compose(ok -> isAuthorized(clientPrincipal, targetAddress, message)).compose(authorized -> {
logger.debug("client [{}] is {}authorized to {}:{}", clientPrincipal.getName(), authorized ? "" : "not ", targetAddress, message.getSubject());
if (authorized) {
try {
processRequest(message, targetAddress, clientPrincipal);
ProtonHelper.accepted(delivery, true);
return Future.succeededFuture();
} catch (DecodeException e) {
return Future.failedFuture(new AmqpErrorException(AmqpError.DECODE_ERROR, "malformed payload"));
}
} else {
return Future.failedFuture(new AmqpErrorException(AmqpError.UNAUTHORIZED_ACCESS, "unauthorized"));
}
}).otherwise(t -> {
if (t instanceof AmqpErrorException) {
AmqpErrorException cause = (AmqpErrorException) t;
MessageHelper.rejected(delivery, cause.asErrorCondition());
} else {
logger.debug("error processing request [resource: {}, op: {}]: {}", targetAddress, message.getSubject(), t.getMessage());
MessageHelper.rejected(delivery, ProtonHelper.condition(AmqpError.INTERNAL_ERROR, "internal error"));
}
return null;
});
}
use of io.vertx.proton.ProtonReceiver in project hono by eclipse.
the class AmqpServiceBaseTest method testHandleReceiverOpenForwardsToEndpoint.
/**
* Verifies that the service notifies a registered endpoint about a client
* that has established a link.
*/
@Test
public void testHandleReceiverOpenForwardsToEndpoint() {
// GIVEN a server with an endpoint
final ResourceIdentifier targetAddress = ResourceIdentifier.from(ENDPOINT, Constants.DEFAULT_TENANT, null);
final AmqpEndpoint endpoint = mock(AmqpEndpoint.class);
when(endpoint.getName()).thenReturn(ENDPOINT);
final AuthorizationService authService = mock(AuthorizationService.class);
when(authService.isAuthorized(Constants.PRINCIPAL_ANONYMOUS, targetAddress, Activity.WRITE)).thenReturn(Future.succeededFuture(Boolean.TRUE));
final AmqpServiceBase<ServiceConfigProperties> server = createServer(endpoint);
server.setAuthorizationService(authService);
// WHEN a client connects to the server using this endpoint
final Target target = getTarget(targetAddress);
final ProtonReceiver receiver = mock(ProtonReceiver.class);
when(receiver.getRemoteTarget()).thenReturn(target);
when(receiver.attachments()).thenReturn(mock(Record.class));
server.handleReceiverOpen(newConnection(Constants.PRINCIPAL_ANONYMOUS), receiver);
// THEN the server delegates link establishment to the endpoint
verify(endpoint).onLinkAttach(any(ProtonConnection.class), eq(receiver), eq(targetAddress));
}
use of io.vertx.proton.ProtonReceiver in project hono by eclipse.
the class CommandAndControlAmqpIT method connectAndSubscribe.
private void connectAndSubscribe(final VertxTestContext ctx, final String commandTargetDeviceId, final AmqpCommandEndpointConfiguration endpointConfig, final BiFunction<ProtonReceiver, ProtonSender, ProtonMessageHandler> commandConsumerFactory, final int expectedNoOfCommands) throws InterruptedException {
final VertxTestContext setup = new VertxTestContext();
final Checkpoint setupDone = setup.checkpoint();
final Checkpoint notificationReceived = setup.checkpoint();
connectToAdapter(tenantId, deviceId, password, () -> createEventConsumer(tenantId, msg -> {
// expect empty notification with TTD -1
ctx.verify(() -> assertThat(msg.getContentType()).isEqualTo(EventConstants.CONTENT_TYPE_EMPTY_NOTIFICATION));
final TimeUntilDisconnectNotification notification = msg.getTimeUntilDisconnectNotification().orElse(null);
log.debug("received notification [{}]", notification);
ctx.verify(() -> assertThat(notification).isNotNull());
if (notification.getTtd() == -1) {
notificationReceived.flag();
}
})).compose(con -> createProducer(null, ProtonQoS.AT_LEAST_ONCE)).compose(sender -> subscribeToCommands(endpointConfig, tenantId, commandTargetDeviceId).map(recv -> {
recv.handler(commandConsumerFactory.apply(recv, sender));
// make sure that there are always enough credits, even if commands are sent faster than answered
recv.flow(expectedNoOfCommands);
return null;
})).onComplete(setup.succeeding(v -> setupDone.flag()));
assertWithMessage("connect and subscribe finished within %s seconds", IntegrationTestSupport.getTestSetupTimeout()).that(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS)).isTrue();
if (setup.failed()) {
ctx.failNow(setup.causeOfFailure());
}
}
Aggregations