org.apache.qpid.proton.amqp.transport.AmqpError Java Examples
The following examples show how to use
org.apache.qpid.proton.amqp.transport.AmqpError.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AbstractProtocolAdapterBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Creates an AMQP error condition for an throwable. * <p> * Non {@link ServiceInvocationException} instances are mapped to {@link AmqpError#PRECONDITION_FAILED}. * * @param t The throwable to map to an error condition. * @return The error condition. */ protected final ErrorCondition getErrorCondition(final Throwable t) { if (ServiceInvocationException.class.isInstance(t)) { final ServiceInvocationException error = (ServiceInvocationException) t; switch (error.getErrorCode()) { case HttpURLConnection.HTTP_BAD_REQUEST: return ProtonHelper.condition(Constants.AMQP_BAD_REQUEST, error.getMessage()); case HttpURLConnection.HTTP_FORBIDDEN: return ProtonHelper.condition(AmqpError.UNAUTHORIZED_ACCESS, error.getMessage()); case HttpUtils.HTTP_TOO_MANY_REQUESTS: return ProtonHelper.condition(AmqpError.RESOURCE_LIMIT_EXCEEDED, error.getMessage()); default: return ProtonHelper.condition(AmqpError.PRECONDITION_FAILED, error.getMessage()); } } else { return ProtonHelper.condition(AmqpError.PRECONDITION_FAILED, t.getMessage()); } }
Example #2
Source File: AuthenticationEndpoint.java From hono with Eclipse Public License 2.0 | 6 votes |
@Override public final void onLinkAttach(final ProtonConnection con, final ProtonSender sender, final ResourceIdentifier targetResource) { if (ProtonQoS.AT_LEAST_ONCE.equals(sender.getRemoteQoS())) { final HonoUser user = Constants.getClientPrincipal(con); sender.setQoS(ProtonQoS.AT_LEAST_ONCE).open(); logger.debug("transferring token to client..."); final Message tokenMsg = ProtonHelper.message(user.getToken()); MessageHelper.addProperty(tokenMsg, AuthenticationConstants.APPLICATION_PROPERTY_TYPE, AuthenticationConstants.TYPE_AMQP_JWT); sender.send(tokenMsg, disposition -> { if (disposition.remotelySettled()) { logger.debug("successfully transferred auth token to client"); } else { logger.debug("failed to transfer auth token to client"); } sender.close(); }); } else { onLinkDetach(sender, ProtonHelper.condition(AmqpError.INVALID_FIELD, "supports AT_LEAST_ONCE delivery mode only")); } }
Example #3
Source File: AMQPSessionCallback.java From activemq-artemis with Apache License 2.0 | 6 votes |
@Override public int sendMessage(MessageReference ref, Message message, ServerConsumer consumer, int deliveryCount) { ProtonServerSenderContext plugSender = (ProtonServerSenderContext) consumer.getProtocolContext(); try { return plugSender.deliverMessage(ref, consumer); } catch (Exception e) { connection.runNow(() -> { plugSender.getSender().setCondition(new ErrorCondition(AmqpError.INTERNAL_ERROR, e.getMessage())); connection.flush(); }); throw new IllegalStateException("Can't deliver message " + e, e); } }
Example #4
Source File: AMQPConnectionCallback.java From activemq-artemis with Apache License 2.0 | 6 votes |
public boolean validateConnection(org.apache.qpid.proton.engine.Connection connection, SASLResult saslResult) { remoteContainerId = connection.getRemoteContainer(); boolean idOK = server.addClientConnection(remoteContainerId, ExtCapability.needUniqueConnection(connection)); if (!idOK) { //https://issues.apache.org/jira/browse/ARTEMIS-728 Map<Symbol, Object> connProp = new HashMap<>(); connProp.put(AmqpSupport.CONNECTION_OPEN_FAILED, "true"); connection.setProperties(connProp); connection.getCondition().setCondition(AmqpError.INVALID_FIELD); Map<Symbol, Symbol> info = new HashMap<>(); info.put(AmqpSupport.INVALID_FIELD, AmqpSupport.CONTAINER_ID); connection.getCondition().setInfo(info); return false; } registeredConnectionId.set(true); return true; }
Example #5
Source File: ProtonServerReceiverContext.java From activemq-artemis with Apache License 2.0 | 6 votes |
private Rejected createRejected(final Exception e) { ErrorCondition condition = new ErrorCondition(); // Set condition if (e instanceof ActiveMQSecurityException) { condition.setCondition(AmqpError.UNAUTHORIZED_ACCESS); } else if (isAddressFull(e)) { condition.setCondition(AmqpError.RESOURCE_LIMIT_EXCEEDED); } else { condition.setCondition(Symbol.valueOf("failed")); } condition.setDescription(e.getMessage()); Rejected rejected = new Rejected(); rejected.setError(condition); return rejected; }
Example #6
Source File: AmqpSupport.java From qpid-jms with Apache License 2.0 | 6 votes |
/** * Given an ErrorCondition instance create a new Exception that best matches * the error type that indicates a non-fatal error usually at the link level * such as link closed remotely or link create failed due to security access * issues. * * @param provider * the AMQP provider instance that originates this exception * @param endpoint * The target of the error. * @param errorCondition * The ErrorCondition returned from the remote peer. * * @return a new Exception instance that best matches the ErrorCondition value. */ public static ProviderException convertToNonFatalException(AmqpProvider provider, Endpoint endpoint, ErrorCondition errorCondition) { ProviderException remoteError = null; if (errorCondition != null && errorCondition.getCondition() != null) { Symbol error = errorCondition.getCondition(); String message = extractErrorMessage(errorCondition); if (error.equals(AmqpError.UNAUTHORIZED_ACCESS)) { remoteError = new ProviderSecurityException(message); } else if (error.equals(AmqpError.RESOURCE_LIMIT_EXCEEDED)) { remoteError = new ProviderResourceAllocationException(message); } else if (error.equals(AmqpError.NOT_FOUND)) { remoteError = new ProviderInvalidDestinationException(message); } else if (error.equals(TransactionErrors.TRANSACTION_ROLLBACK)) { remoteError = new ProviderTransactionRolledBackException(message); } else { remoteError = new ProviderException(message); } } else if (remoteError == null) { remoteError = new ProviderException("Unknown error from remote peer"); } return remoteError; }
Example #7
Source File: AmqpServiceBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Closes an expired client connection. * <p> * A connection is considered expired if the {@link HonoUser#isExpired()} method * of the user principal attached to the connection returns {@code true}. * * @param con The client connection. */ protected final void closeExpiredConnection(final ProtonConnection con) { if (!con.isDisconnected()) { final HonoUser clientPrincipal = Constants.getClientPrincipal(con); if (clientPrincipal != null) { log.debug("client's [{}] access token has expired, closing connection", clientPrincipal.getName()); con.disconnectHandler(null); con.closeHandler(null); con.setCondition(ProtonHelper.condition(AmqpError.UNAUTHORIZED_ACCESS, "access token expired")); con.close(); con.disconnect(); publishConnectionClosedEvent(con); } } }
Example #8
Source File: VertxBasedAmqpProtocolAdapterTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the connection is rejected as the adapter is disabled. */ @Test public void testConnectionFailsIfAdapterIsDisabled() { // GIVEN an AMQP adapter that requires devices to authenticate config.setAuthenticationRequired(true); final VertxBasedAmqpProtocolAdapter adapter = givenAnAmqpAdapter(); // AND given a tenant for which the AMQP Adapter is disabled givenAConfiguredTenant(TEST_TENANT_ID, false); // WHEN a device connects final Device authenticatedDevice = new Device(TEST_TENANT_ID, TEST_DEVICE); final Record record = new RecordImpl(); record.set(AmqpAdapterConstants.KEY_CLIENT_DEVICE, Device.class, authenticatedDevice); final ProtonConnection deviceConnection = mock(ProtonConnection.class); when(deviceConnection.attachments()).thenReturn(record); adapter.onConnectRequest(deviceConnection); @SuppressWarnings("unchecked") final ArgumentCaptor<Handler<AsyncResult<ProtonConnection>>> openHandler = ArgumentCaptor .forClass(Handler.class); verify(deviceConnection).openHandler(openHandler.capture()); openHandler.getValue().handle(Future.succeededFuture(deviceConnection)); // THEN the adapter does not accept the incoming connection request. final ArgumentCaptor<ErrorCondition> errorConditionCaptor = ArgumentCaptor.forClass(ErrorCondition.class); verify(deviceConnection).setCondition(errorConditionCaptor.capture()); assertEquals(AmqpError.UNAUTHORIZED_ACCESS, errorConditionCaptor.getValue().getCondition()); }
Example #9
Source File: VertxBasedAmqpProtocolAdapterTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the connection is rejected as the connection limit for * the given tenant is exceeded. */ @Test public void testConnectionFailsIfTenantLevelConnectionLimitIsExceeded() { // GIVEN an AMQP adapter that requires devices to authenticate config.setAuthenticationRequired(true); final VertxBasedAmqpProtocolAdapter adapter = givenAnAmqpAdapter(); // WHEN the connection limit for the given tenant exceeds when(resourceLimitChecks.isConnectionLimitReached(any(TenantObject.class), any(SpanContext.class))) .thenReturn(Future.succeededFuture(Boolean.TRUE)); // WHEN a device connects final Device authenticatedDevice = new Device(TEST_TENANT_ID, TEST_DEVICE); final Record record = new RecordImpl(); record.set(AmqpAdapterConstants.KEY_CLIENT_DEVICE, Device.class, authenticatedDevice); final ProtonConnection deviceConnection = mock(ProtonConnection.class); when(deviceConnection.attachments()).thenReturn(record); adapter.onConnectRequest(deviceConnection); @SuppressWarnings("unchecked") final ArgumentCaptor<Handler<AsyncResult<ProtonConnection>>> openHandler = ArgumentCaptor .forClass(Handler.class); verify(deviceConnection).openHandler(openHandler.capture()); openHandler.getValue().handle(Future.succeededFuture(deviceConnection)); // THEN the adapter does not accept the incoming connection request. final ArgumentCaptor<ErrorCondition> errorConditionCaptor = ArgumentCaptor.forClass(ErrorCondition.class); verify(deviceConnection).setCondition(errorConditionCaptor.capture()); assertEquals(AmqpError.UNAUTHORIZED_ACCESS, errorConditionCaptor.getValue().getCondition()); }
Example #10
Source File: MappingAndDelegatingCommandHandlerTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that a command message with an address that contains a tenant which doesn't * match the scope of the command receiver link gets rejected. */ @SuppressWarnings("unchecked") @Test public void testMapForMessageHavingAddressWithInvalidTenant() { // GIVEN a command message with an address that contains an // invalid tenant final String deviceId = "4711"; final Message message = getValidCommandMessage(deviceId); message.setAddress(String.format("%s/%s/%s", CommandConstants.COMMAND_ENDPOINT, "wrong-tenant", deviceId)); // WHEN mapping and delegating the command final ProtonDelivery delivery = mock(ProtonDelivery.class); mappingAndDelegatingCommandHandler.mapAndDelegateIncomingCommandMessage(Constants.DEFAULT_TENANT, delivery, message); // THEN the disposition is REJECTED verify(delivery).disposition( argThat(state -> AmqpError.UNAUTHORIZED_ACCESS.equals(((Rejected) state).getError().getCondition())), eq(true)); // and the message is not being delegated verify(sender, never()).send(any(Message.class), any(Handler.class)); }
Example #11
Source File: AmqpSupportTest.java From qpid-jms with Apache License 2.0 | 6 votes |
@Test public void testCreateRedirectionExceptionWithNoNetworkHost() throws URISyntaxException { AmqpProvider mockProvider = Mockito.mock(AmqpProvider.class); Mockito.when(mockProvider.getRemoteURI()).thenReturn(new URI("amqp://localhost:5672")); ErrorCondition condition = new ErrorCondition(); Map<Symbol, Object> info = new HashMap<>(); info.put(AmqpSupport.PORT, "5672"); info.put(AmqpSupport.OPEN_HOSTNAME, "localhost"); info.put(AmqpSupport.SCHEME, "amqp"); info.put(AmqpSupport.PATH, "websocket"); condition.setInfo(info); Symbol error = AmqpError.INTERNAL_ERROR; String message = "Failed to connect"; Exception result = AmqpSupport.createRedirectException(mockProvider, error, message, condition); assertNotNull(result); assertFalse(result instanceof ProviderConnectionRedirectedException); assertTrue(result instanceof ProviderException); }
Example #12
Source File: StatusCodeMapper.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Creates an exception for an AMQP error condition. * * @param condition The error condition. * @param description The error description or {@code null} if not available. * @return The exception. * @throws NullPointerException if error is {@code null}. */ public static final ServiceInvocationException from(final Symbol condition, final String description) { Objects.requireNonNull(condition); if (AmqpError.RESOURCE_LIMIT_EXCEEDED.equals(condition)) { return new ClientErrorException(HttpURLConnection.HTTP_FORBIDDEN, description); } else if (AmqpError.UNAUTHORIZED_ACCESS.equals(condition)) { return new ClientErrorException(HttpURLConnection.HTTP_FORBIDDEN, description); } else if (AmqpError.INTERNAL_ERROR.equals(condition)) { return new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR, description); } else if (Constants.AMQP_BAD_REQUEST.equals(condition)) { return new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, description); } else { return new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND, description); } }
Example #13
Source File: AmqpSupportTest.java From qpid-jms with Apache License 2.0 | 6 votes |
@Test public void testCreateRedirectionExceptionWithEmptyNetworkHost() throws URISyntaxException { AmqpProvider mockProvider = Mockito.mock(AmqpProvider.class); Mockito.when(mockProvider.getRemoteURI()).thenReturn(new URI("amqp://localhost:5672")); ErrorCondition condition = new ErrorCondition(); Map<Symbol, Object> info = new HashMap<>(); info.put(AmqpSupport.PORT, "5672"); info.put(AmqpSupport.NETWORK_HOST, ""); info.put(AmqpSupport.OPEN_HOSTNAME, "localhost"); info.put(AmqpSupport.SCHEME, "amqp"); info.put(AmqpSupport.PATH, "websocket"); condition.setInfo(info); Symbol error = AmqpError.INTERNAL_ERROR; String message = "Failed to connect"; Exception result = AmqpSupport.createRedirectException(mockProvider, error, message, condition); assertNotNull(result); assertFalse(result instanceof ProviderConnectionRedirectedException); assertTrue(result instanceof ProviderException); }
Example #14
Source File: AmqpSupportTest.java From qpid-jms with Apache License 2.0 | 6 votes |
@Test public void testCreateRedirectionExceptionWithInvalidPort() throws URISyntaxException { AmqpProvider mockProvider = Mockito.mock(AmqpProvider.class); Mockito.when(mockProvider.getRemoteURI()).thenReturn(new URI("amqp://localhost:5672")); ErrorCondition condition = new ErrorCondition(); Map<Symbol, Object> info = new HashMap<>(); info.put(AmqpSupport.PORT, "L5672"); info.put(AmqpSupport.OPEN_HOSTNAME, "localhost"); info.put(AmqpSupport.NETWORK_HOST, "localhost"); info.put(AmqpSupport.SCHEME, "amqp"); info.put(AmqpSupport.PATH, "websocket"); condition.setInfo(info); Symbol error = AmqpError.INTERNAL_ERROR; String message = "Failed to connect"; Exception result = AmqpSupport.createRedirectException(mockProvider, error, message, condition); assertNotNull(result); assertFalse(result instanceof ProviderConnectionRedirectedException); assertTrue(result instanceof ProviderException); }
Example #15
Source File: AmqpSupportTest.java From qpid-jms with Apache License 2.0 | 5 votes |
@Test public void testCreateRedirectionException() throws URISyntaxException { ErrorCondition condition = new ErrorCondition(); AmqpProvider mockProvider = Mockito.mock(AmqpProvider.class); Mockito.when(mockProvider.getRemoteURI()).thenReturn(new URI("amqp://localhost:5672")); Map<Symbol, Object> info = new HashMap<>(); info.put(AmqpSupport.PORT, "5672"); info.put(AmqpSupport.OPEN_HOSTNAME, "localhost.localdomain"); info.put(AmqpSupport.NETWORK_HOST, "localhost"); info.put(AmqpSupport.SCHEME, "amqp"); info.put(AmqpSupport.PATH, "/websocket"); condition.setInfo(info); Symbol error = AmqpError.INTERNAL_ERROR; String message = "Failed to connect"; Exception result = AmqpSupport.createRedirectException(mockProvider, error, message, condition); assertNotNull(result); assertTrue(result instanceof ProviderConnectionRedirectedException); ProviderConnectionRedirectedException pre = (ProviderConnectionRedirectedException) result; URI redirection = pre.getRedirectionURI(); assertEquals(5672, redirection.getPort()); assertTrue("localhost.localdomain", redirection.getQuery().contains("amqp.vhost=localhost.localdomain")); assertEquals("localhost", redirection.getHost()); assertEquals("amqp", redirection.getScheme()); assertEquals("/websocket", redirection.getPath()); }
Example #16
Source File: AmqpSecurityTest.java From activemq-artemis with Apache License 2.0 | 5 votes |
@Test(timeout = 60000) public void testSendAndRejected() throws Exception { AmqpClient client = createAmqpClient(guestUser, guestPass); client.setValidator(new AmqpValidator() { @Override public void inspectOpenedResource(Sender sender) { ErrorCondition condition = sender.getRemoteCondition(); if (condition != null && condition.getCondition() != null) { if (!condition.getCondition().equals(AmqpError.UNAUTHORIZED_ACCESS)) { markAsInvalid("Should have been tagged with unauthorized access error"); } } else { markAsInvalid("Sender should have been opened with an error"); } } }); AmqpConnection connection = addConnection(client.connect()); AmqpSession session = connection.createSession(); try { try { session.createSender(getQueueName()); fail("Should not be able to consume here."); } catch (Exception ex) { instanceLog.debug("Caught expected exception"); } connection.getStateInspector().assertValid(); } finally { connection.close(); } }
Example #17
Source File: AmqpSupportTest.java From qpid-jms with Apache License 2.0 | 5 votes |
@Test public void testCreateRedirectionExceptionWithNoRedirectInfo() throws URISyntaxException { AmqpProvider mockProvider = Mockito.mock(AmqpProvider.class); Mockito.when(mockProvider.getRemoteURI()).thenReturn(new URI("amqp://localhost:5672")); ErrorCondition condition = new ErrorCondition(); Symbol error = AmqpError.INTERNAL_ERROR; String message = "Failed to connect"; Exception result = AmqpSupport.createRedirectException(mockProvider, error, message, condition); assertNotNull(result); assertFalse(result instanceof ProviderConnectionRedirectedException); assertTrue(result instanceof ProviderException); }
Example #18
Source File: AmqpSupport.java From qpid-jms with Apache License 2.0 | 5 votes |
/** * Given an ErrorCondition instance create a new Exception that best matches * the error type that indicates the connection creation failed for some reason. * * @param provider * the AMQP provider instance that originates this exception * @param endpoint * The target of the error. * @param errorCondition * The ErrorCondition returned from the remote peer. * * @return a new Exception instance that best matches the ErrorCondition value. */ public static ProviderConnectionRemotelyClosedException convertToConnectionClosedException(AmqpProvider provider, Endpoint endpoint, ErrorCondition errorCondition) { ProviderConnectionRemotelyClosedException remoteError = null; if (errorCondition != null && errorCondition.getCondition() != null) { Symbol error = errorCondition.getCondition(); String message = extractErrorMessage(errorCondition); if (error.equals(AmqpError.UNAUTHORIZED_ACCESS)) { remoteError = new ProviderConnectionSecurityException(message); } else if (error.equals(AmqpError.RESOURCE_LIMIT_EXCEEDED)) { remoteError = new ProviderConnectionResourceAllocationException(message); } else if (error.equals(ConnectionError.CONNECTION_FORCED)) { remoteError = new ProviderConnectionRemotelyClosedException(message); } else if (error.equals(AmqpError.NOT_FOUND)) { remoteError = new ProviderConnectionResourceNotFoundException(message); } else if (error.equals(ConnectionError.REDIRECT)) { remoteError = createRedirectException(provider, error, message, errorCondition); } else if (error.equals(AmqpError.INVALID_FIELD)) { Map<?, ?> info = errorCondition.getInfo(); if (info != null && CONTAINER_ID.equals(info.get(INVALID_FIELD))) { remoteError = new ProviderInvalidClientIDException(message); } else { remoteError = new ProviderConnectionRemotelyClosedException(message); } } else { remoteError = new ProviderConnectionRemotelyClosedException(message); } } else if (remoteError == null) { remoteError = new ProviderConnectionRemotelyClosedException("Unknown error from remote peer"); } return remoteError; }
Example #19
Source File: ProtonHandler.java From activemq-artemis with Apache License 2.0 | 5 votes |
private void internalHandlerError(Exception e) { log.warn(e.getMessage(), e); ErrorCondition error = new ErrorCondition(); error.setCondition(AmqpError.INTERNAL_ERROR); error.setDescription("Unrecoverable error: " + (e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage())); connection.setCondition(error); connection.close(); flush(); }
Example #20
Source File: AmqpSecurityTest.java From activemq-artemis with Apache License 2.0 | 5 votes |
@Test(timeout = 30000) public void testConsumerNotAuthorizedToCreateQueues() throws Exception { AmqpClient client = createAmqpClient(noprivUser, noprivPass); client.setValidator(new AmqpValidator() { @Override public void inspectOpenedResource(Sender sender) { ErrorCondition condition = sender.getRemoteCondition(); if (condition != null && condition.getCondition() != null) { if (!condition.getCondition().equals(AmqpError.UNAUTHORIZED_ACCESS)) { markAsInvalid("Should have been tagged with unauthorized access error"); } } else { markAsInvalid("Sender should have been opened with an error"); } } }); AmqpConnection connection = client.connect(); try { AmqpSession session = connection.createSession(); try { session.createReceiver(getQueueName(getPrecreatedQueueSize() + 1)); fail("Should not be able to consume here."); } catch (Exception ex) { instanceLog.debug("Caught expected exception"); } connection.getStateInspector().assertValid(); } finally { connection.close(); } }
Example #21
Source File: AmqpSecurityTest.java From activemq-artemis with Apache License 2.0 | 5 votes |
@Test(timeout = 30000) public void testReceiverNotAuthorized() throws Exception { AmqpClient client = createAmqpClient(noprivUser, noprivPass); client.setValidator(new AmqpValidator() { @Override public void inspectOpenedResource(Receiver receiver) { ErrorCondition condition = receiver.getRemoteCondition(); if (condition != null && condition.getCondition() != null) { if (!condition.getCondition().equals(AmqpError.UNAUTHORIZED_ACCESS)) { markAsInvalid("Should have been tagged with unauthorized access error"); } } else { markAsInvalid("Receiver should have been opened with an error"); } } }); AmqpConnection connection = client.connect(); try { AmqpSession session = connection.createSession(); try { session.createReceiver(getQueueName()); fail("Should not be able to consume here."); } catch (Exception ex) { instanceLog.debug("Caught expected exception"); } connection.getStateInspector().assertValid(); } finally { connection.close(); } }
Example #22
Source File: TransportImpl.java From qpid-proton-j with Apache License 2.0 | 5 votes |
@Override public void closed(TransportException error) { if (!_closeReceived || error != null) { // Set an error condition, but only if one was not already set if(!_conditionSet) { if(error instanceof TransportDecodeException) { setCondition(new ErrorCondition(AmqpError.DECODE_ERROR, error.getMessage())); } else { String description = error == null ? "connection aborted" : error.toString(); setCondition(new ErrorCondition(ConnectionError.FRAMING_ERROR, description)); } } _head_closed = true; } if (_conditionSet && !postedTransportError) { put(Event.Type.TRANSPORT_ERROR, this); postedTransportError = true; } if (!postedTailClosed) { put(Event.Type.TRANSPORT_TAIL_CLOSED, this); postedTailClosed = true; maybePostClosed(); } }
Example #23
Source File: SimpleAuthenticationServer.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Handles a request from a client to establish a link for receiving messages from this server. * * @param con the connection to the client. * @param sender the sender created for the link. */ @Override protected void handleSenderOpen(final ProtonConnection con, final ProtonSender sender) { final Source remoteSource = sender.getRemoteSource(); LOG.debug("client [{}] wants to open a link for receiving messages [address: {}]", con.getRemoteContainer(), remoteSource); try { final ResourceIdentifier targetResource = getResourceIdentifier(remoteSource.getAddress()); final AmqpEndpoint endpoint = getEndpoint(targetResource); if (endpoint == null) { LOG.debug("no endpoint registered for node [{}]", targetResource); con.setCondition(ProtonHelper.condition(AmqpError.NOT_FOUND, "no such node")).close(); } else { final HonoUser user = Constants.getClientPrincipal(con); if (Constants.SUBJECT_ANONYMOUS.equals(user.getName())) { con.setCondition(ProtonHelper.condition(AmqpError.UNAUTHORIZED_ACCESS, "client must authenticate using SASL")).close(); } else { Constants.copyProperties(con, sender); sender.setSource(sender.getRemoteSource()); endpoint.onLinkAttach(con, sender, targetResource); } } } catch (final IllegalArgumentException e) { LOG.debug("client has provided invalid resource identifier as source address", e); con.setCondition(ProtonHelper.condition(AmqpError.INVALID_FIELD, "malformed source address")).close(); } }
Example #24
Source File: HonoConnectionImplTest.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Verifies that the attempt to create a receiver fails with a * {@code ServiceInvocationException} if the remote peer refuses * to open the link with an error condition. * * @param ctx The vert.x test context. */ @Test public void testCreateReceiverFailsForErrorCondition(final VertxTestContext ctx) { testCreateReceiverFails(ctx, () -> new ErrorCondition(AmqpError.RESOURCE_LIMIT_EXCEEDED, "unauthorized"), cause -> { return cause instanceof ServiceInvocationException; }); }
Example #25
Source File: HonoConnectionImplTest.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Verifies that the attempt to create a sender fails with a * {@code ServiceInvocationException} if the remote peer refuses * to open the link with an error condition. * * @param ctx The vert.x test context. */ @Test public void testCreateSenderFailsForErrorCondition(final VertxTestContext ctx) { testCreateSenderFails( ctx, () -> new ErrorCondition(AmqpError.RESOURCE_LIMIT_EXCEEDED, "unauthorized"), cause -> { return cause instanceof ServiceInvocationException; }); }
Example #26
Source File: VertxBasedAmqpProtocolAdapterTest.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Verifies that the connection is rejected as the connection limit for * the adapter is exceeded. */ @Test public void testConnectionFailsIfAdapterLevelConnectionLimitIsExceeded() { // GIVEN an AMQP adapter that requires devices to authenticate config.setAuthenticationRequired(true); final VertxBasedAmqpProtocolAdapter adapter = givenAnAmqpAdapter(); // WHEN the adapter's connection limit exceeds when(connectionLimitManager.isLimitExceeded()).thenReturn(true); // WHEN a device connects final Device authenticatedDevice = new Device(TEST_TENANT_ID, TEST_DEVICE); final Record record = new RecordImpl(); record.set(AmqpAdapterConstants.KEY_CLIENT_DEVICE, Device.class, authenticatedDevice); final ProtonConnection deviceConnection = mock(ProtonConnection.class); when(deviceConnection.attachments()).thenReturn(record); adapter.onConnectRequest(deviceConnection); @SuppressWarnings("unchecked") final ArgumentCaptor<Handler<AsyncResult<ProtonConnection>>> openHandler = ArgumentCaptor .forClass(Handler.class); verify(deviceConnection).openHandler(openHandler.capture()); openHandler.getValue().handle(Future.succeededFuture(deviceConnection)); // THEN the connection count should be incremented when the connection is opened final InOrder metricsInOrderVerifier = inOrder(metrics); metricsInOrderVerifier.verify(metrics).incrementConnections(TEST_TENANT_ID); // AND the adapter should close the connection right after it opened it final ArgumentCaptor<Handler<AsyncResult<ProtonConnection>>> closeHandler = ArgumentCaptor.forClass(Handler.class); verify(deviceConnection).closeHandler(closeHandler.capture()); closeHandler.getValue().handle(Future.succeededFuture()); final ArgumentCaptor<ErrorCondition> errorConditionCaptor = ArgumentCaptor.forClass(ErrorCondition.class); verify(deviceConnection).setCondition(errorConditionCaptor.capture()); assertEquals(AmqpError.UNAUTHORIZED_ACCESS, errorConditionCaptor.getValue().getCondition()); // AND the connection count should be decremented accordingly when the connection is closed metricsInOrderVerifier.verify(metrics).decrementConnections(TEST_TENANT_ID); verify(metrics).reportConnectionAttempt(ConnectionAttemptOutcome.ADAPTER_CONNECTION_LIMIT_EXCEEDED); }
Example #27
Source File: AmqpServiceBase.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Closes a link for an unknown target address. * <p> * The link is closed with AMQP error code <em>amqp:not-found</em>. * * @param con The connection that the link belongs to. * @param link The link. * @param address The unknown target address. */ protected final void handleUnknownEndpoint(final ProtonConnection con, final ProtonLink<?> link, final ResourceIdentifier address) { log.info("client [container: {}] wants to establish link for unknown endpoint [address: {}]", con.getRemoteContainer(), address); link.setCondition( ProtonHelper.condition( AmqpError.NOT_FOUND, String.format("no endpoint registered for address %s", address))); link.close(); }
Example #28
Source File: AmqpServiceBase.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Handles a request from a client to establish a link for sending messages to this server. * The already established connection must have an authenticated user as principal for doing the authorization check. * * @param con the connection to the client. * @param receiver the receiver created for the link. */ protected void handleReceiverOpen(final ProtonConnection con, final ProtonReceiver receiver) { if (receiver.getRemoteTarget().getAddress() == null) { log.debug("client [container: {}] wants to open an anonymous link for sending messages to arbitrary addresses, closing link ...", con.getRemoteContainer()); receiver.setCondition(ProtonHelper.condition(AmqpError.NOT_ALLOWED, "anonymous relay not supported")); receiver.close(); } else { log.debug("client [container: {}] wants to open a link [address: {}] for sending messages", con.getRemoteContainer(), receiver.getRemoteTarget()); try { final ResourceIdentifier targetResource = getResourceIdentifier(receiver.getRemoteTarget().getAddress()); final AmqpEndpoint endpoint = getEndpoint(targetResource); if (endpoint == null) { handleUnknownEndpoint(con, receiver, targetResource); } else { final HonoUser user = Constants.getClientPrincipal(con); getAuthorizationService().isAuthorized(user, targetResource, Activity.WRITE).onComplete(authAttempt -> { if (authAttempt.succeeded() && authAttempt.result()) { Constants.copyProperties(con, receiver); receiver.setSource(receiver.getRemoteSource()); receiver.setTarget(receiver.getRemoteTarget()); endpoint.onLinkAttach(con, receiver, targetResource); } else { log.debug("subject [{}] is not authorized to WRITE to [{}]", user.getName(), targetResource); receiver.setCondition(ProtonHelper.condition(AmqpError.UNAUTHORIZED_ACCESS.toString(), "unauthorized")); receiver.close(); } }); } } catch (final IllegalArgumentException e) { log.debug("client has provided invalid resource identifier as target address", e); receiver.setCondition(ProtonHelper.condition(AmqpError.NOT_FOUND, "no such address")); receiver.close(); } } }
Example #29
Source File: AmqpServiceBase.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Handles a request from a client to establish a link for receiving messages from this server. * * @param con the connection to the client. * @param sender the sender created for the link. */ protected void handleSenderOpen(final ProtonConnection con, final ProtonSender sender) { final Source remoteSource = sender.getRemoteSource(); log.debug("client [container: {}] wants to open a link [address: {}] for receiving messages", con.getRemoteContainer(), remoteSource); try { final ResourceIdentifier targetResource = getResourceIdentifier(remoteSource.getAddress()); final AmqpEndpoint endpoint = getEndpoint(targetResource); if (endpoint == null) { handleUnknownEndpoint(con, sender, targetResource); } else { final HonoUser user = Constants.getClientPrincipal(con); getAuthorizationService().isAuthorized(user, targetResource, Activity.READ).onComplete(authAttempt -> { if (authAttempt.succeeded() && authAttempt.result()) { Constants.copyProperties(con, sender); sender.setSource(sender.getRemoteSource()); sender.setTarget(sender.getRemoteTarget()); endpoint.onLinkAttach(con, sender, targetResource); } else { log.debug("subject [{}] is not authorized to READ from [{}]", user.getName(), targetResource); sender.setCondition(ProtonHelper.condition(AmqpError.UNAUTHORIZED_ACCESS.toString(), "unauthorized")); sender.close(); } }); } } catch (final IllegalArgumentException e) { log.debug("client has provided invalid resource identifier as target address", e); sender.setCondition(ProtonHelper.condition(AmqpError.NOT_FOUND, "no such address")); sender.close(); } }
Example #30
Source File: RequestResponseEndpoint.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Handles a client's request to establish a link for sending service invocation requests. * <p> * Configure and check the receiver link of the endpoint. * The remote link of the receiver must not demand the AT_MOST_ONCE QoS (not supported). * The receiver link itself is configured with the AT_LEAST_ONCE QoS and grants the configured credits * ({@link ServiceConfigProperties#getReceiverLinkCredit()}) with autoAcknowledge. * <p> * Handling of request messages is delegated to * {@link #handleRequestMessage(ProtonConnection, ProtonReceiver, ResourceIdentifier, ProtonDelivery, Message)}. * * @param con The AMQP connection that the link is part of. * @param receiver The ProtonReceiver that has already been created for this endpoint. * @param targetAddress The resource identifier for this endpoint (see {@link ResourceIdentifier} for details). */ @Override public final void onLinkAttach(final ProtonConnection con, final ProtonReceiver receiver, final ResourceIdentifier targetAddress) { if (ProtonQoS.AT_MOST_ONCE.equals(receiver.getRemoteQoS())) { logger.debug("client wants to use unsupported AT MOST ONCE delivery mode for endpoint [{}], closing link ...", getName()); receiver.setCondition(ProtonHelper.condition(AmqpError.PRECONDITION_FAILED.toString(), "endpoint requires AT_LEAST_ONCE QoS")); receiver.close(); } else { logger.debug("establishing link for receiving request messages from client [{}]", receiver.getName()); receiver.setQoS(ProtonQoS.AT_LEAST_ONCE); receiver.setAutoAccept(true); // settle received messages if the handler succeeds receiver.setTarget(receiver.getRemoteTarget()); receiver.setSource(receiver.getRemoteSource()); // We do manual flow control, credits are replenished after responses have been sent. receiver.setPrefetch(0); // set up handlers receiver.handler((delivery, message) -> { try { handleRequestMessage(con, receiver, targetAddress, delivery, message); } catch (final Exception ex) { logger.warn("error handling message", ex); ProtonHelper.released(delivery, true); } }); HonoProtonHelper.setCloseHandler(receiver, remoteClose -> onLinkDetach(receiver)); HonoProtonHelper.setDetachHandler(receiver, remoteDetach -> onLinkDetach(receiver)); // acknowledge the remote open receiver.open(); // send out initial credits, after opening logger.debug("flowing {} credits to client", config.getReceiverLinkCredit()); receiver.flow(config.getReceiverLinkCredit()); } }