Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions RMQClient.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
1029A0E22087A97E00C72924 /* ConnectionDeadlockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1029A0E12087A97E00C72924 /* ConnectionDeadlockTests.swift */; };
4DF6E46D27F6E98100C43208 /* RMQClient.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEE7FE911C3BCA6000DF8C4F /* RMQClient.framework */; };
5CE0C5292B873842000087B7 /* ConnectionUpdateSecretTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE0C5282B873842000087B7 /* ConnectionUpdateSecretTest.swift */; };
70311B0B21ED538600AE1804 /* RMQConnectionDefaults.h in Headers */ = {isa = PBXBuildFile; fileRef = 70311B0A21ED538600AE1804 /* RMQConnectionDefaults.h */; };
70338A2421FBAA7C00C9069D /* TLSConnectionIntegrationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70338A2321FBAA7C00C9069D /* TLSConnectionIntegrationTest.swift */; };
705359A921D174A400CF6456 /* TestCertificates in Resources */ = {isa = PBXBuildFile; fileRef = 705359A821D174A400CF6456 /* TestCertificates */; };
Expand Down Expand Up @@ -238,6 +239,7 @@
/* Begin PBXFileReference section */
1029A0E12087A97E00C72924 /* ConnectionDeadlockTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionDeadlockTests.swift; sourceTree = "<group>"; };
4DF6E43627F6E90700C43208 /* MemoryTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MemoryTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
5CE0C5282B873842000087B7 /* ConnectionUpdateSecretTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionUpdateSecretTest.swift; sourceTree = "<group>"; };
70311B0A21ED538600AE1804 /* RMQConnectionDefaults.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RMQConnectionDefaults.h; sourceTree = "<group>"; };
70338A2321FBAA7C00C9069D /* TLSConnectionIntegrationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TLSConnectionIntegrationTest.swift; sourceTree = "<group>"; };
705359A821D174A400CF6456 /* TestCertificates */ = {isa = PBXFileReference; lastKnownFileType = folder; path = TestCertificates; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -491,6 +493,7 @@
AE26FA2F1C970E9A00CDBBAA /* Channels */ = {
isa = PBXGroup;
children = (
5CE0C5282B873842000087B7 /* ConnectionUpdateSecretTest.swift */,
AE26FA2D1C970DF100CDBBAA /* RMQChannelContract.swift */,
AE8279841C8D86110013ADD1 /* ChannelAllocationTest.swift */,
AE8AD2681CC545ED00229444 /* RMQFramesetValidatorTest.swift */,
Expand Down Expand Up @@ -1292,6 +1295,7 @@
AE9DB00D1D12AA120005F44B /* RMQTransactionalConfirmationsTest.swift in Sources */,
AE11F1B21D155C8A007AD330 /* RMQMessageTest.swift in Sources */,
AE9DB0091D11FDED0005F44B /* ConfirmationsSpy.swift in Sources */,
5CE0C5292B873842000087B7 /* ConnectionUpdateSecretTest.swift in Sources */,
AEA8A7621CC97C7900371E38 /* RMQGCDSerialQueueTest.swift in Sources */,
AE59345B1C8735FA00560A73 /* ChannelSpy.swift in Sources */,
AE8AD25C1CC4E67F00229444 /* RMQUnallocatedChannelTest.swift in Sources */,
Expand Down
10 changes: 10 additions & 0 deletions RMQClient/RMQConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,4 +242,14 @@
*/
- (nonnull id<RMQChannel>)createChannel;

/*!
* @brief Update secret.
* This method updates the secret used to authenticate this connection.
* It is used when secrets have an expiration date and need to be renewed, like OAuth 2 tokens.
* @param secret The new secret.
* @param reason The reason for the secret update.
*/
- (void)updateSecret:(nonnull NSString *)secret
reason:(nonnull NSString *)reason;

@end
16 changes: 16 additions & 0 deletions RMQClient/RMQConnection.m
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,14 @@ - (void)start {
return ch;
}

- (void)updateSecret:(NSString *)secret
reason:(NSString *)reason
{
[self.commandQueue enqueue:^{
[self sendFrameset:[[RMQFrameset alloc] initWithChannelNumber:@0 method:[self methodForUpdateSecret:secret reason:reason]]];
}];
}

- (BOOL)hasCompletedHandshake {
return self.handshakeComplete;
}
Expand Down Expand Up @@ -746,6 +754,14 @@ - (void)closeAllUserChannels {
}
}

- (RMQConnectionUpdateSecret *)methodForUpdateSecret:(NSString *)secret
reason:(NSString *)reason {
RMQLongstr *secretLongstr = [[RMQLongstr alloc] init:secret];
RMQShortstr *reasonShortstr = [[RMQShortstr alloc] init:reason];
return [[RMQConnectionUpdateSecret alloc] initWithSecret:secretLongstr
reason:reasonShortstr];
}

- (RMQConnectionClose *)amqClose {
return [[RMQConnectionClose alloc] initWithReplyCode:[[RMQShort alloc] init:200]
replyText:[[RMQShortstr alloc] init:@"Goodbye"]
Expand Down
2 changes: 2 additions & 0 deletions RMQClient/RMQMethodMap.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ + (NSDictionary *)methodMap {
@[@(10), @(51)] : [RMQConnectionCloseOk class],
@[@(10), @(60)] : [RMQConnectionBlocked class],
@[@(10), @(61)] : [RMQConnectionUnblocked class],
@[@(10), @(70)] : [RMQConnectionUpdateSecret class],
@[@(10), @(71)] : [RMQConnectionUpdateSecretOk class],
@[@(20), @(10)] : [RMQChannelOpen class],
@[@(20), @(11)] : [RMQChannelOpenOk class],
@[@(20), @(20)] : [RMQChannelFlow class],
Expand Down
9 changes: 9 additions & 0 deletions RMQClient/RMQMethods.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ typedef NS_OPTIONS(NSUInteger, RMQConnectionOpenOptions) {
@end
@interface RMQConnectionUnblocked : RMQValue <RMQMethod>

@end
@interface RMQConnectionUpdateSecret : RMQValue <RMQMethod>
@property (nonnull, copy, nonatomic, readonly) RMQLongstr *secret;
@property (nonnull, copy, nonatomic, readonly) RMQShortstr *reason;
- (nonnull instancetype)initWithSecret:(nonnull RMQLongstr *)secret
reason:(nonnull RMQShortstr *)reason;
@end
@interface RMQConnectionUpdateSecretOk : RMQValue <RMQMethod>

@end
@interface RMQChannelOpen : RMQValue <RMQMethod>
@property (nonnull, copy, nonatomic, readonly) RMQShortstr *reserved1;
Expand Down
91 changes: 91 additions & 0 deletions RMQClient/RMQMethods.m
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,97 @@ - (NSNumber *)frameTypeID { return @1; }
- (BOOL)hasContent { return NO; }


- (instancetype)initWithDecodedFrame:(NSArray *)frame {
self = [super init];
if (self) {
self.payloadArguments = @[];
}
return self;
}

- (NSData *)amqEncoded {
NSMutableData *encoded = [NSMutableData new];
[encoded appendData:[[RMQShort alloc] init:self.classID.integerValue].amqEncoded];
[encoded appendData:[[RMQShort alloc] init:self.methodID.integerValue].amqEncoded];
for (id<RMQEncodable>arg in self.payloadArguments) {
[encoded appendData:arg.amqEncoded];
}
return encoded;
}

@end

@interface RMQConnectionUpdateSecret ()
@property (nonnull, copy, nonatomic, readwrite) RMQLongstr *secret;
@property (nonnull, copy, nonatomic, readwrite) RMQShortstr *reason;
@property (nonatomic, readwrite) NSArray *payloadArguments;
@property (nonatomic, readwrite) BOOL hasContent;
@end

@implementation RMQConnectionUpdateSecret

+ (NSArray *)propertyClasses {
return @[[RMQLongstr class],
[RMQShortstr class]];
}
- (NSNumber *)classID { return @10; }
- (NSNumber *)methodID { return @70; }
- (Class)syncResponse { return [RMQConnectionUpdateSecretOk class]; }
- (NSNumber *)frameTypeID { return @1; }
- (BOOL)hasContent { return NO; }

- (nonnull instancetype)initWithSecret:(nonnull RMQLongstr *)secret
reason:(nonnull RMQShortstr *)reason {
self = [super init];
if (self) {
self.secret = secret;
self.reason = reason;
self.payloadArguments = @[self.secret,
self.reason];
}
return self;
}

- (instancetype)initWithDecodedFrame:(NSArray *)frame {
self = [super init];
if (self) {
self.secret = ((RMQLongstr *)frame[0]);
self.reason = ((RMQShortstr *)frame[1]);
self.payloadArguments = @[self.secret,
self.reason];
}
return self;
}

- (NSData *)amqEncoded {
NSMutableData *encoded = [NSMutableData new];
[encoded appendData:[[RMQShort alloc] init:self.classID.integerValue].amqEncoded];
[encoded appendData:[[RMQShort alloc] init:self.methodID.integerValue].amqEncoded];
for (id<RMQEncodable>arg in self.payloadArguments) {
[encoded appendData:arg.amqEncoded];
}
return encoded;
}

@end

@interface RMQConnectionUpdateSecretOk ()
@property (nonatomic, readwrite) NSArray *payloadArguments;
@property (nonatomic, readwrite) BOOL hasContent;
@end

@implementation RMQConnectionUpdateSecretOk

+ (NSArray *)propertyClasses {
return @[];
}
- (NSNumber *)classID { return @10; }
- (NSNumber *)methodID { return @71; }
- (Class)syncResponse { return nil; }
- (NSNumber *)frameTypeID { return @1; }
- (BOOL)hasContent { return NO; }


- (instancetype)initWithDecodedFrame:(NSArray *)frame {
self = [super init];
if (self) {
Expand Down
26 changes: 26 additions & 0 deletions RMQClientTests/ConnectionUpdateSecretTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// ConnectionUpdateSecretTest.swift
// RMQClientTests
//
// Created by Andrew Urban on 22.02.2024.
// Copyright © 2024 VMware. All rights reserved.
//

import XCTest

final class ConnectionUpdateSecretTest: XCTestCase {

func testSendsUpdateSecretMethod() {
let (transport, q, conn, _) = ConnectionWithFakesHelper.connectionAfterHandshake()

let secret = "someSecret"
let reason = "some test reason"

conn.updateSecret(secret, reason: reason);

try? q.step()

transport.assertClientSentMethod(MethodFixtures.connectionUpdateSecret(secret, reason: reason), channelNumber: 0)
}

}
5 changes: 5 additions & 0 deletions RMQClientTests/MethodFixtures.swift
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ class MethodFixtures {
static func connectionTuneOk() -> RMQConnectionTuneOk {
return RMQConnectionTuneOk(channelMax: RMQShort(65535), frameMax: RMQLong(RMQFrameMax), heartbeat: RMQShort(60))
}

static func connectionUpdateSecret(_ secret: String,
reason: String) -> RMQConnectionUpdateSecret {
return RMQConnectionUpdateSecret(secret: RMQLongstr(secret), reason: RMQShortstr(reason))
}

static func exchangeBind(_ source: String, destination: String, routingKey: String) -> RMQExchangeBind {
return RMQExchangeBind(destination: destination, source: source, routingKey: routingKey)
Expand Down
30 changes: 30 additions & 0 deletions codegen/amqp0-9-1.extended.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
WARNING: Modified from the official 0-9-1 specification XML by
the addition of:
confirm.select and confirm.select-ok,
connection.update-secret and connection.update-secret-ok,
exchange.bind and exchange.bind-ok,
exchange.unbind and exchange.unbind-ok,
basic.nack,
Expand Down Expand Up @@ -914,6 +915,35 @@
<chassis name = "server" implement = "MUST"/>
<chassis name = "client" implement = "MUST"/>
</method>

<method name = "update-secret" synchronous = "1" index = "70" label = "update secret">
<doc>
This method updates the secret used to authenticate this connection. It is used when secrets have an expiration date and need to be renewed, like OAuth 2 tokens.
</doc>

<chassis name = "client" implement = "MUST" />
<response name = "update-secret-ok" />

<field name = "secret" domain = "longstr">
<doc>
The new secret.
</doc>
</field>

<field name = "reason" domain = "shortstr">
<doc>
The reason for the secret update.
</doc>
</field>
</method>

<method name = "update-secret-ok" synchronous = "1" index = "71" label = "update secret response">
<doc>
This method confirms the updated secret is valid.
</doc>
<chassis name = "server" implement = "MUST" />
</method>

</class>

<!-- == CHANNEL ========================================================== -->
Expand Down
14 changes: 1 addition & 13 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
FROM ubuntu:18.04

RUN apt-get update -y
RUN apt-get install -y gnupg2 wget
RUN wget -O - "https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc" | apt-key add -

COPY apt/sources.list.d/bintray.rabbitmq.list /etc/apt/sources.list.d/bintray.rabbitmq.list
COPY apt/preferences.d/erlang /etc/apt/preferences.d/erlang

RUN apt-get update -y

RUN apt-get upgrade -y && \
apt-get install -y rabbitmq-server
FROM rabbitmq:3.12-management

COPY docker-entrypoint.sh /
COPY certificates/*.pem /etc/rabbitmq/
Expand Down
3 changes: 0 additions & 3 deletions docker/apt/preferences.d/erlang

This file was deleted.

2 changes: 0 additions & 2 deletions docker/apt/sources.list.d/bintray.rabbitmq.list

This file was deleted.