Skip to content

Commit 7ddec19

Browse files
authored
Merge pull request #135 from liammclennan/add-expression-indexes
Add expression indexes
2 parents 5db0f31 + bca7325 commit 7ddec19

10 files changed

Lines changed: 220 additions & 1 deletion

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace Seq.Api.Model.Indexes
2+
{
3+
/// <summary>
4+
/// An index over the event stream. May be one of several types discriminated by <see cref="IndexedEntityType"/>.
5+
/// </summary>
6+
public class IndexEntity: Entity
7+
{
8+
/// <summary>
9+
/// The `Id` of the associated entity (Signal, Alert or Expression index).
10+
/// </summary>
11+
public string IndexedEntityId { get; set; }
12+
13+
/// <summary>
14+
/// The type of this index.
15+
/// </summary>
16+
public IndexedEntityType IndexedEntityType { get; set; }
17+
18+
/// <summary>
19+
/// The owner / creator of this index.
20+
/// </summary>
21+
public string OwnerUsername { get; set; }
22+
23+
/// <summary>
24+
/// The name of this index. May not be applicable to all index types.
25+
/// </summary>
26+
public string Label { get; set; }
27+
28+
/// <summary>
29+
/// The storage used by this index.
30+
/// </summary>
31+
public ulong StorageBytes { get; set; }
32+
}
33+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
namespace Seq.Api.Model.Indexes
2+
{
3+
/// <summary>
4+
/// The type of the index.
5+
/// </summary>
6+
public enum IndexedEntityType
7+
{
8+
/// <summary>
9+
/// A predicate index for a signal expression.
10+
/// </summary>
11+
Signal,
12+
13+
/// <summary>
14+
/// An expression index.
15+
/// </summary>
16+
ExpressionIndex,
17+
18+
/// <summary>
19+
/// A predicate index for an alert filter.
20+
/// </summary>
21+
Alert,
22+
}
23+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace Seq.Api.Model.Indexing
2+
{
3+
/// <summary>
4+
/// An index based on an expression.
5+
/// </summary>
6+
public class ExpressionIndexEntity: Entity
7+
{
8+
/// <summary>
9+
/// The expression to be indexed.
10+
/// </summary>
11+
public string Expression { get; set; }
12+
13+
/// <summary>
14+
/// A user-provided description of the index.
15+
/// </summary>
16+
public string Description { get; set; }
17+
}
18+
}

src/Seq.Api/Model/Settings/SettingName.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using System;
1616
using Seq.Api.Model.Apps;
1717
using Seq.Api.Model.Updates;
18+
using Seq.Api.Model.Users;
1819
using Seq.Api.ResourceGroups;
1920

2021
namespace Seq.Api.Model.Settings
@@ -124,6 +125,16 @@ public enum SettingName
124125
/// Seq will stop accepting new events.
125126
/// </summary>
126127
MinimumFreeStorageSpace,
128+
129+
/// <summary>
130+
/// A dictionary of `(string, string)` pairs that will be used to initialize the
131+
/// <see cref="UserEntity.Preferences"/> property when preparing new user entities
132+
/// with <see cref="UsersResourceGroup.TemplateAsync"/>, and with automatically
133+
/// provisioning SSO users (when enabled).
134+
/// </summary>
135+
/// <remarks>User preference keys are unconstrained; the Seq UI uses a number of these, but
136+
/// alternative interfaces and integrations may add additional items to this collection.</remarks>
137+
NewUserPreferences,
127138

128139
/// <summary>
129140
/// A comma-separated list of role ids that will be assigned to new users by default.

src/Seq.Api/Model/Signals/SignalEntity.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ public SignalEntity()
6767
/// If <c>true</c>, the signal can only be modified by users with the <see cref="Permission.Project"/> permission.
6868
/// </summary>
6969
public bool IsProtected { get; set; }
70+
71+
/// <summary>
72+
/// If <c>true</c>, the signal has no backing index.
73+
/// </summary>
74+
public bool IsIndexSuppressed { get; set; }
7075

7176
/// <summary>
7277
/// How the signal is grouped in the Seq UI.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System.Collections.Generic;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using Seq.Api.Model;
5+
using Seq.Api.Model.Indexing;
6+
7+
namespace Seq.Api.ResourceGroups
8+
{
9+
/// <summary>
10+
/// Perform operations on expression indexes.
11+
/// </summary>
12+
public class ExpressionIndexesResourceGroup: ApiResourceGroup
13+
{
14+
internal ExpressionIndexesResourceGroup(ILoadResourceGroup connection) : base("ExpressionIndexes", connection)
15+
{
16+
}
17+
18+
/// <summary>
19+
/// Retrieve expression indexes.
20+
/// </summary>
21+
/// <param name="cancellationToken"><see cref="CancellationToken"/> allowing the operation to be canceled.</param>
22+
/// <returns>A list containing matching expression indexes.</returns>
23+
public async Task<List<ExpressionIndexEntity>> ListAsync(CancellationToken cancellationToken = default)
24+
{
25+
return await GroupListAsync<ExpressionIndexEntity>("Items", cancellationToken: cancellationToken).ConfigureAwait(false);
26+
}
27+
28+
/// <summary>
29+
/// Construct an expression index with server defaults pre-initialized.
30+
/// </summary>
31+
/// <param name="cancellationToken"><see cref="CancellationToken"/> allowing the operation to be canceled.</param>
32+
/// <returns>The unsaved expression index.</returns>
33+
public async Task<ExpressionIndexEntity> TemplateAsync(CancellationToken cancellationToken = default)
34+
{
35+
return await GroupGetAsync<ExpressionIndexEntity>("Template", cancellationToken: cancellationToken).ConfigureAwait(false);
36+
}
37+
38+
/// <summary>
39+
/// Add a new expression index.
40+
/// </summary>
41+
/// <param name="entity">The expression index to add.</param>
42+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
43+
/// <returns>The expression index, with server-allocated properties such as <see cref="Entity.Id"/> initialized.</returns>
44+
public async Task<ExpressionIndexEntity> AddAsync(ExpressionIndexEntity entity, CancellationToken cancellationToken = default)
45+
{
46+
return await GroupCreateAsync<ExpressionIndexEntity, ExpressionIndexEntity>(entity, cancellationToken: cancellationToken).ConfigureAwait(false);
47+
}
48+
49+
/// <summary>
50+
/// Remove an existing expression index.
51+
/// </summary>
52+
/// <param name="entity">The expression index to remove.</param>
53+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
54+
/// <returns>A task indicating completion.</returns>
55+
public async Task RemoveAsync(ExpressionIndexEntity entity, CancellationToken cancellationToken = default)
56+
{
57+
await Client.DeleteAsync(entity, "Self", entity, cancellationToken: cancellationToken).ConfigureAwait(false);
58+
}
59+
}
60+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using Seq.Api.Model.Alerting;
6+
using Seq.Api.Model.Indexes;
7+
using Seq.Api.Model.Indexing;
8+
using Seq.Api.Model.Signals;
9+
10+
namespace Seq.Api.ResourceGroups
11+
{
12+
/// <summary>
13+
/// Statistics about indexes.
14+
/// </summary>
15+
public class IndexesResourceGroup : ApiResourceGroup
16+
{
17+
internal IndexesResourceGroup(ILoadResourceGroup connection)
18+
: base("Indexes", connection)
19+
{
20+
}
21+
/// <summary>
22+
/// Retrieve the index with the given id; throws if the entity does not exist.
23+
/// </summary>
24+
/// <param name="id">The id of the index.</param>
25+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
26+
/// <returns>The index.</returns>
27+
public async Task<SignalEntity> FindAsync(string id, CancellationToken cancellationToken = default)
28+
{
29+
if (id == null) throw new ArgumentNullException(nameof(id));
30+
return await GroupGetAsync<SignalEntity>("Item", new Dictionary<string, object> { { "id", id } }, cancellationToken).ConfigureAwait(false);
31+
}
32+
33+
34+
/// <summary>
35+
/// Retrieve statistics on all indexes.
36+
/// </summary>
37+
/// <param name="cancellationToken"><see cref="CancellationToken"/> allowing the operation to be canceled.</param>
38+
/// <returns>A list containing matching expression indexes.</returns>
39+
public async Task<List<IndexEntity>> ListAsync(CancellationToken cancellationToken = default)
40+
{
41+
return await GroupListAsync<IndexEntity>("Items", cancellationToken: cancellationToken).ConfigureAwait(false);
42+
}
43+
44+
/// <summary>
45+
/// Suppress an index. Not all index types can be suppressed: signal indexes do support suppression, in the case
46+
/// of which the <see cref="SignalEntity.IsIndexSuppressed"/> flag will be set to <c langword="false"/>.
47+
/// Expression indexes can only be suppressed by deleting the associated <see cref="ExpressionIndexEntity"/>
48+
/// and alert indexes can only be suppressed by deleting the corresponding <see cref="AlertEntity"/>.
49+
/// </summary>
50+
/// <param name="entity">The index to suppress.</param>
51+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> allowing the operation to be canceled.</param>
52+
/// <returns>A task indicating completion.</returns>
53+
public async Task SuppressAsync(IndexEntity entity, CancellationToken cancellationToken = default)
54+
{
55+
await Client.DeleteAsync(entity, "Self", entity, cancellationToken: cancellationToken).ConfigureAwait(false);
56+
}
57+
}
58+
}

src/Seq.Api/ResourceGroups/SignalsResourceGroup.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public async Task<SignalEntity> AddAsync(SignalEntity entity, CancellationToken
7878
{
7979
return await GroupCreateAsync<SignalEntity, SignalEntity>(entity, cancellationToken: cancellationToken).ConfigureAwait(false);
8080
}
81+
8182
/// <summary>
8283
/// Remove an existing signal.
8384
/// </summary>

src/Seq.Api/Seq.Api.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<Description>Client library for the Seq HTTP API.</Description>
4-
<VersionPrefix>2024.2.0</VersionPrefix>
4+
<VersionPrefix>2024.3.0</VersionPrefix>
55
<Authors>Datalust;Contributors</Authors>
66
<TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
77
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

src/Seq.Api/SeqConnection.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,22 @@ public void Dispose()
149149
/// Perform operations on queries and filter expressions.
150150
/// </summary>
151151
public ExpressionsResourceGroup Expressions => new ExpressionsResourceGroup(this);
152+
153+
/// <summary>
154+
/// Perform operations on expression indexes.
155+
/// </summary>
156+
public ExpressionIndexesResourceGroup ExpressionIndexes => new ExpressionIndexesResourceGroup(this);
152157

153158
/// <summary>
154159
/// Perform operations on NuGet feeds.
155160
/// </summary>
156161
public FeedsResourceGroup Feeds => new FeedsResourceGroup(this);
157162

163+
/// <summary>
164+
/// Statistics about indexes.
165+
/// </summary>
166+
public IndexesResourceGroup Indexes => new IndexesResourceGroup(this);
167+
158168
/// <summary>
159169
/// Perform operations on the Seq license certificate.
160170
/// </summary>

0 commit comments

Comments
 (0)