From 0625d62a7815b0a907dfe836236bca8bd1e71563 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Fri, 10 Nov 2023 15:41:55 +0200 Subject: [PATCH 01/26] Add DirectoryClient interface. --- src/main/java/com/aserto/DirClient.java | 158 ++++++++++++++++++ src/main/java/com/aserto/DirectoryClient.java | 110 ++++-------- src/test/java/DirClientTest.java | 54 ++++++ 3 files changed, 240 insertions(+), 82 deletions(-) create mode 100644 src/main/java/com/aserto/DirClient.java create mode 100644 src/test/java/DirClientTest.java diff --git a/src/main/java/com/aserto/DirClient.java b/src/main/java/com/aserto/DirClient.java new file mode 100644 index 0000000..1db18c8 --- /dev/null +++ b/src/main/java/com/aserto/DirClient.java @@ -0,0 +1,158 @@ +package com.aserto; + +import com.aserto.directory.common.v2.ObjectTypeIdentifier; +import com.aserto.directory.common.v2.PaginationRequest; +import com.aserto.directory.exporter.v2.ExporterGrpc; +import com.aserto.directory.importer.v2.ImporterGrpc; +import com.aserto.directory.reader.v2.*; +import com.aserto.directory.writer.v2.WriterGrpc; +import com.aserto.directory.common.v2.Object; +import io.grpc.ManagedChannel; + +public class DirClient { + private ReaderGrpc.ReaderBlockingStub readerClient; + private WriterGrpc.WriterBlockingStub writerClient; + private ImporterGrpc.ImporterBlockingStub importerClient; + private ExporterGrpc.ExporterBlockingStub exporterClient; + private ManagedChannel channel; + private ManagedChannel readerChannel; + private ManagedChannel writerChannel; + private ManagedChannel importerChannel; + private ManagedChannel exporterChannel; + + public DirClient(ManagedChannel channel) { + this.readerClient = ReaderGrpc.newBlockingStub(channel); + this.writerClient = WriterGrpc.newBlockingStub(channel); + this.importerClient = ImporterGrpc.newBlockingStub(channel); + this.exporterClient = ExporterGrpc.newBlockingStub(channel); + this.channel = channel; + } + + public DirClient(ManagedChannel readerChannel, + ManagedChannel writerChannel, + ManagedChannel importerChannel, + ManagedChannel exporterChannel) { + + if (readerChannel != null) { + this.readerClient = ReaderGrpc.newBlockingStub(readerChannel); + this.readerChannel = readerChannel; + } + + if (writerChannel != null) { + this.writerClient = WriterGrpc.newBlockingStub(writerChannel); + this.writerChannel = writerChannel; + } + + if (importerChannel != null) { + this.importerClient = ImporterGrpc.newBlockingStub(importerChannel); + this.importerChannel = importerChannel; + } + + if (exporterChannel != null) { + this.exporterClient = ExporterGrpc.newBlockingStub(exporterChannel); + this.exporterChannel = exporterChannel; + } + } + + public ReaderGrpc.ReaderBlockingStub getReaderClient() { + return readerClient; + } + + public WriterGrpc.WriterBlockingStub getWriterClient() { + return writerClient; + } + + public ImporterGrpc.ImporterBlockingStub getImporterClient() { + return importerClient; + } + + public ExporterGrpc.ExporterBlockingStub getExporterClient() { + return exporterClient; + } + class Result { + private T[] results; + private String nextPageToken; + + public Result(T[] results, String nextPageToken) { + this.results = results; + this.nextPageToken = nextPageToken; + } + + public T[] getResults() { + return results; + } + + public String getNextPageToken() { + return nextPageToken; + } + } + + public Result getObjects(String objectType, Integer pageSize, String nextPageToken) { + GetObjectsRequest.Builder builder = GetObjectsRequest.newBuilder(); + + PaginationRequest paginationRequest = PaginationRequest.newBuilder() + .setSize(pageSize) + .setToken(nextPageToken) + .build(); + ObjectTypeIdentifier objectIdentifier = ObjectTypeIdentifier.newBuilder() + .setName(objectType) + .build(); + + GetObjectsRequest request = builder + .setPage(paginationRequest) + .setParam(objectIdentifier) + .build(); + GetObjectsResponse response = readerClient.getObjects(request); + String nextToken = response.getPage().getNextToken(); + + + Object[] objects = response.getResultsList().toArray(new Object[0]); + return new Result<>(objects, nextToken); + } + + public void close() { + if (channel != null) { + channel.shutdown(); + } + + if (readerChannel != null) { + readerChannel.shutdown(); + } + + if (writerChannel != null) { + writerChannel.shutdown(); + } + + if (importerChannel != null) { + importerChannel.shutdown(); + } + + if (exporterChannel != null) { + exporterChannel.shutdown(); + } + } + + public void closeReader() { + if (readerChannel != null) { + readerChannel.shutdown(); + } + } + + public void closeWriter() { + if (writerChannel != null) { + writerChannel.shutdown(); + } + } + + public void closeImporter() { + if (importerChannel != null) { + importerChannel.shutdown(); + } + } + + public void closeExporter() { + if (exporterChannel != null) { + exporterChannel.shutdown(); + } + } +} diff --git a/src/main/java/com/aserto/DirectoryClient.java b/src/main/java/com/aserto/DirectoryClient.java index 824b586..daea0ae 100644 --- a/src/main/java/com/aserto/DirectoryClient.java +++ b/src/main/java/com/aserto/DirectoryClient.java @@ -1,86 +1,32 @@ package com.aserto; -import com.aserto.directory.common.v2.ObjectTypeIdentifier; -import com.aserto.directory.common.v2.PaginationRequest; -import com.aserto.directory.exporter.v2.ExporterGrpc; -import com.aserto.directory.importer.v2.ImporterGrpc; import com.aserto.directory.reader.v2.*; -import com.aserto.directory.writer.v2.WriterGrpc; -import com.aserto.directory.common.v2.Object; -import io.grpc.ManagedChannel; - -public class DirectoryClient { - private ReaderGrpc.ReaderBlockingStub readerClient; - private WriterGrpc.WriterBlockingStub writerClient; - private ImporterGrpc.ImporterBlockingStub importerClient; - private ExporterGrpc.ExporterBlockingStub exporterClient; - private ManagedChannel channel; - - public DirectoryClient(ManagedChannel channel) { - this.readerClient = ReaderGrpc.newBlockingStub(channel); - this.writerClient = WriterGrpc.newBlockingStub(channel); - this.importerClient = ImporterGrpc.newBlockingStub(channel); - this.exporterClient = ExporterGrpc.newBlockingStub(channel); - this.channel = channel; - } - - public ReaderGrpc.ReaderBlockingStub getReaderClient() { - return readerClient; - } - - public WriterGrpc.WriterBlockingStub getWriterClient() { - return writerClient; - } - - public ImporterGrpc.ImporterBlockingStub getImporterClient() { - return importerClient; - } - - public ExporterGrpc.ExporterBlockingStub getExporterClient() { - return exporterClient; - } - class Result { - private T[] results; - private String nextPageToken; - - public Result(T[] results, String nextPageToken) { - this.results = results; - this.nextPageToken = nextPageToken; - } - - public T[] getResults() { - return results; - } - - public String getNextPageToken() { - return nextPageToken; - } - } - - public Result getObjects(String objectType, Integer pageSize, String nextPageToken) { - GetObjectsRequest.Builder builder = GetObjectsRequest.newBuilder(); - - PaginationRequest paginationRequest = PaginationRequest.newBuilder() - .setSize(pageSize) - .setToken(nextPageToken) - .build(); - ObjectTypeIdentifier objectIdentifier = ObjectTypeIdentifier.newBuilder() - .setName(objectType) - .build(); - - GetObjectsRequest request = builder - .setPage(paginationRequest) - .setParam(objectIdentifier) - .build(); - GetObjectsResponse response = readerClient.getObjects(request); - String nextToken = response.getPage().getNextToken(); - - - Object[] objects = response.getResultsList().toArray(new Object[0]); - return new Result<>(objects, nextToken); - } - - public void close() { - channel.shutdown(); - } +import com.aserto.directory.writer.v2.DeleteObjectResponse; +import com.aserto.directory.writer.v2.DeleteRelationResponse; +import com.aserto.directory.writer.v2.SetObjectResponse; +import com.aserto.directory.writer.v2.SetRelationResponse; +import com.google.protobuf.Struct; + +public interface DirectoryClient { + public GetObjectResponse getObject(String type, String id, boolean withRelations); + public GetObjectsResponse getObjects(String type, int pageSize, String pageToken); + public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, + String subjectId, String subjectRelation, boolean withObjects); + public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, + String subjectType, String subjectId, String subjectRelation, + boolean withObjects, int pageSize, String pageToken); + public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId, boolean trace); + public CheckPermissionResponse checkPermission(String objectType, String objectId, String relationName, + String subjectType, String subjectId, boolean trace); + + public CheckResponse check(String objectType, String objectId, String relationName, + String subjectType, String subjectId, boolean trace); + + public SetObjectResponse setObject(String type, String id, String displayName, Struct properties, String hash); + public DeleteObjectResponse deleteObject(String type, String id, boolean withRelations); + public SetRelationResponse setRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId, String subjectRelation, String hash); + public DeleteRelationResponse deleteRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId, String subjectRelation); } diff --git a/src/test/java/DirClientTest.java b/src/test/java/DirClientTest.java new file mode 100644 index 0000000..70f68b2 --- /dev/null +++ b/src/test/java/DirClientTest.java @@ -0,0 +1,54 @@ +import com.aserto.DirClient; +import io.grpc.ManagedChannel; +import io.grpc.inprocess.InProcessChannelBuilder; +import io.grpc.inprocess.InProcessServerBuilder; +import io.grpc.testing.GrpcCleanupRule; +import org.junit.Rule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.*; + + +public class DirClientTest { + @Rule + public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule(); + + private ManagedChannel channel; + + @BeforeEach + public void setUp() throws IOException { + // Generate a unique in-process server name. + String serverName = InProcessServerBuilder.generateName(); + + // Create a client channel and register for automatic graceful shutdown. + channel = grpcCleanup.register( + InProcessChannelBuilder.forName(serverName).directExecutor().build()); + } + + @Test + void createDirectoryClientWithReader() { + // Arrange & Act + DirClient dirClient = new DirClient(channel, null, null, null); + + // Assert + assertNotEquals(null, dirClient.getReaderClient()); + assertNull(dirClient.getWriterClient()); + assertNull(dirClient.getImporterClient()); + assertNull(dirClient.getExporterClient()); + } + + @Test + void createDirectoryClientsWithSameChannel() { + // Arrange & Act + DirClient dirClient = new DirClient(channel); + + // Assert + assertNotEquals(null, dirClient.getReaderClient()); + assertNotEquals(null, dirClient.getWriterClient()); + assertNotEquals(null, dirClient.getImporterClient()); + assertNotEquals(null, dirClient.getExporterClient()); + } +} From 89522b6dffe0559e56198c9cabd900a08e2166ec Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Wed, 15 Nov 2023 18:57:50 +0200 Subject: [PATCH 02/26] Add Interfaces for directory clients. Implement the reader, writer and manifest interfaces. Bump dependencies. --- pom.xml | 10 +- src/main/java/com/aserto/ChannelBuilder.java | 6 +- .../{DirClient.java => DirClientBuilder.java} | 94 ++++-- src/main/java/com/aserto/DirectoryClient.java | 296 ++++++++++++++++-- .../com/aserto/DirectoryClientExporter.java | 4 + .../com/aserto/DirectoryClientImporter.java | 4 + .../com/aserto/DirectoryClientManifest.java | 11 + .../com/aserto/DirectoryClientReader.java | 20 ++ .../com/aserto/DirectoryClientWriter.java | 16 + ...t.java => DirectoryClientBuilderTest.java} | 24 +- 10 files changed, 406 insertions(+), 79 deletions(-) rename src/main/java/com/aserto/{DirClient.java => DirClientBuilder.java} (58%) create mode 100644 src/main/java/com/aserto/DirectoryClientExporter.java create mode 100644 src/main/java/com/aserto/DirectoryClientImporter.java create mode 100644 src/main/java/com/aserto/DirectoryClientManifest.java create mode 100644 src/main/java/com/aserto/DirectoryClientReader.java create mode 100644 src/main/java/com/aserto/DirectoryClientWriter.java rename src/test/java/{DirClientTest.java => DirectoryClientBuilderTest.java} (58%) diff --git a/pom.xml b/pom.xml index 5f0e8ce..6a5cf67 100644 --- a/pom.xml +++ b/pom.xml @@ -37,11 +37,11 @@ - 8 - 8 + 17 + 17 UTF-8 - 1.58.0 + 1.59.0 IntegrationTest @@ -49,12 +49,12 @@ com.aserto java-authorizer - 0.20.6 + 0.20.7 com.aserto java-directory - 0.0.1 + 0.30.1 diff --git a/src/main/java/com/aserto/ChannelBuilder.java b/src/main/java/com/aserto/ChannelBuilder.java index 2fe06fd..f685b67 100644 --- a/src/main/java/com/aserto/ChannelBuilder.java +++ b/src/main/java/com/aserto/ChannelBuilder.java @@ -90,7 +90,11 @@ public ManagedChannel build() throws SSLException { .intercept(MetadataUtils.newAttachHeadersInterceptor(metadata)); boolean insecure = cfg.getInsecure(); - boolean caSpecified = !cfg.getCaCertPath().isEmpty(); + + boolean caSpecified = true; + if (cfg.getCaCertPath() == null || cfg.getCaCertPath().isEmpty()) { + caSpecified = false; + } if (insecure) { SslContext context = GrpcSslContexts.forClient() diff --git a/src/main/java/com/aserto/DirClient.java b/src/main/java/com/aserto/DirClientBuilder.java similarity index 58% rename from src/main/java/com/aserto/DirClient.java rename to src/main/java/com/aserto/DirClientBuilder.java index 1db18c8..eeb12f4 100644 --- a/src/main/java/com/aserto/DirClient.java +++ b/src/main/java/com/aserto/DirClientBuilder.java @@ -1,37 +1,43 @@ package com.aserto; +//import com.aserto.directory.common.v3.ObjectTypeIdentifier; import com.aserto.directory.common.v2.ObjectTypeIdentifier; -import com.aserto.directory.common.v2.PaginationRequest; -import com.aserto.directory.exporter.v2.ExporterGrpc; -import com.aserto.directory.importer.v2.ImporterGrpc; -import com.aserto.directory.reader.v2.*; -import com.aserto.directory.writer.v2.WriterGrpc; -import com.aserto.directory.common.v2.Object; +import com.aserto.directory.common.v3.PaginationRequest; +import com.aserto.directory.exporter.v3.ExporterGrpc; +import com.aserto.directory.importer.v3.ImporterGrpc; +import com.aserto.directory.model.v3.ModelGrpc; +import com.aserto.directory.reader.v3.*; +import com.aserto.directory.writer.v3.WriterGrpc; +import com.aserto.directory.common.v3.Object; import io.grpc.ManagedChannel; -public class DirClient { +public class DirClientBuilder { private ReaderGrpc.ReaderBlockingStub readerClient; private WriterGrpc.WriterBlockingStub writerClient; private ImporterGrpc.ImporterBlockingStub importerClient; private ExporterGrpc.ExporterBlockingStub exporterClient; + private ModelGrpc.ModelBlockingStub modelClient; private ManagedChannel channel; private ManagedChannel readerChannel; private ManagedChannel writerChannel; private ManagedChannel importerChannel; private ManagedChannel exporterChannel; + private ManagedChannel modelChannel; - public DirClient(ManagedChannel channel) { + public DirClientBuilder(ManagedChannel channel) { this.readerClient = ReaderGrpc.newBlockingStub(channel); this.writerClient = WriterGrpc.newBlockingStub(channel); this.importerClient = ImporterGrpc.newBlockingStub(channel); this.exporterClient = ExporterGrpc.newBlockingStub(channel); + this.modelClient = ModelGrpc.newBlockingStub(channel); this.channel = channel; } - public DirClient(ManagedChannel readerChannel, - ManagedChannel writerChannel, - ManagedChannel importerChannel, - ManagedChannel exporterChannel) { + public DirClientBuilder(ManagedChannel readerChannel, + ManagedChannel writerChannel, + ManagedChannel importerChannel, + ManagedChannel exporterChannel, + ManagedChannel modelChannel) { if (readerChannel != null) { this.readerClient = ReaderGrpc.newBlockingStub(readerChannel); @@ -52,6 +58,11 @@ public DirClient(ManagedChannel readerChannel, this.exporterClient = ExporterGrpc.newBlockingStub(exporterChannel); this.exporterChannel = exporterChannel; } + + if (modelClient != null) { + this.modelClient = ModelGrpc.newBlockingStub(modelChannel); + this.modelChannel = modelChannel; + } } public ReaderGrpc.ReaderBlockingStub getReaderClient() { @@ -69,6 +80,11 @@ public ImporterGrpc.ImporterBlockingStub getImporterClient() { public ExporterGrpc.ExporterBlockingStub getExporterClient() { return exporterClient; } + + public ModelGrpc.ModelBlockingStub getModelClient() { + return modelClient; + } + class Result { private T[] results; private String nextPageToken; @@ -87,28 +103,28 @@ public String getNextPageToken() { } } - public Result getObjects(String objectType, Integer pageSize, String nextPageToken) { - GetObjectsRequest.Builder builder = GetObjectsRequest.newBuilder(); - - PaginationRequest paginationRequest = PaginationRequest.newBuilder() - .setSize(pageSize) - .setToken(nextPageToken) - .build(); - ObjectTypeIdentifier objectIdentifier = ObjectTypeIdentifier.newBuilder() - .setName(objectType) - .build(); - - GetObjectsRequest request = builder - .setPage(paginationRequest) - .setParam(objectIdentifier) - .build(); - GetObjectsResponse response = readerClient.getObjects(request); - String nextToken = response.getPage().getNextToken(); - - - Object[] objects = response.getResultsList().toArray(new Object[0]); - return new Result<>(objects, nextToken); - } +// public Result getObjects(String objectType, Integer pageSize, String nextPageToken) { +// GetObjectsRequest.Builder builder = GetObjectsRequest.newBuilder(); +// +// PaginationRequest paginationRequest = PaginationRequest.newBuilder() +// .setSize(pageSize) +// .setToken(nextPageToken) +// .build(); +// ObjectTypeIdentifier objectIdentifier = ObjectTypeIdentifier.newBuilder() +// .setName(objectType) +// .build(); +// +// GetObjectsRequest request = builder +// .setPage(paginationRequest) +// .setParam(objectIdentifier) +// .build(); +// GetObjectsResponse response = readerClient.getObjects(request); +// String nextToken = response.getPage().getNextToken(); +// +// +// Object[] objects = response.getResultsList().toArray(new Object[0]); +// return new Result<>(objects, nextToken); +// } public void close() { if (channel != null) { @@ -130,6 +146,10 @@ public void close() { if (exporterChannel != null) { exporterChannel.shutdown(); } + + if (modelChannel != null) { + modelChannel.shutdown(); + } } public void closeReader() { @@ -155,4 +175,10 @@ public void closeExporter() { exporterChannel.shutdown(); } } + + public void closeModel() { + if (modelChannel != null) { + modelChannel.shutdown(); + } + } } diff --git a/src/main/java/com/aserto/DirectoryClient.java b/src/main/java/com/aserto/DirectoryClient.java index daea0ae..853f8a1 100644 --- a/src/main/java/com/aserto/DirectoryClient.java +++ b/src/main/java/com/aserto/DirectoryClient.java @@ -1,32 +1,274 @@ package com.aserto; -import com.aserto.directory.reader.v2.*; -import com.aserto.directory.writer.v2.DeleteObjectResponse; -import com.aserto.directory.writer.v2.DeleteRelationResponse; -import com.aserto.directory.writer.v2.SetObjectResponse; -import com.aserto.directory.writer.v2.SetRelationResponse; +import com.aserto.directory.common.v3.ObjectIdentifier; +import com.aserto.directory.common.v3.PaginationRequest; +import com.aserto.directory.common.v3.Relation; +import com.aserto.directory.exporter.v3.ExporterGrpc; +import com.aserto.directory.importer.v3.ImporterGrpc; +import com.aserto.directory.model.v3.*; +import com.aserto.directory.reader.v3.*; +import com.aserto.directory.writer.v3.*; +import com.google.protobuf.ByteString; import com.google.protobuf.Struct; +import com.aserto.directory.common.v3.Object; + + +import com.google.protobuf.Timestamp; +import io.grpc.ManagedChannel; + +import javax.net.ssl.SSLException; +import java.time.Instant; +import java.util.Iterator; +import java.util.List; + +public class DirectoryClient implements DirectoryClientReader, DirectoryClientWriter, DirectoryClientManifest { + private ReaderGrpc.ReaderBlockingStub readerClient; + private WriterGrpc.WriterBlockingStub writerClient; + private ImporterGrpc.ImporterBlockingStub importerClient; + private ExporterGrpc.ExporterBlockingStub exporterClient; + private ModelGrpc.ModelBlockingStub modelClient; + + public DirectoryClient(DirClientBuilder dirClientBuilder) { + readerClient = dirClientBuilder.getReaderClient(); + writerClient = dirClientBuilder.getWriterClient(); + modelClient = dirClientBuilder.getModelClient(); + } + + + @Override + public GetObjectResponse getObject(String type, String id, boolean withRelations) { + return readerClient.getObject(GetObjectRequest.newBuilder() + .setObjectType(type) + .setObjectId(id) + .setWithRelations(withRelations) + .build()); + } + + @Override + public GetObjectsResponse getObjects(String type, int pageSize, String pageToken) { + return readerClient.getObjects(GetObjectsRequest.newBuilder() + .setObjectType(type) + .setPage(buildPaginationRequest(pageSize, pageToken)) + .build()); + } + + public GetObjectManyRequest getObjectManyRequest(List objectIdentifiers) { + return GetObjectManyRequest.newBuilder() + .addAllParam(new ObjectIdentifierList(objectIdentifiers)) + .build(); + } + + private PaginationRequest buildPaginationRequest(int pageSize, String pageToken) { + return PaginationRequest.newBuilder() + .setSize(pageSize) + .setToken(pageToken) + .build(); + } + + @Override + public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects) { + return readerClient.getRelation(GetRelationRequest.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relationName) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .setSubjectRelation(subjectRelation) + .setWithObjects(withObjects) + .build()); + } + + @Override + public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects, int pageSize, String pageToken) { + return readerClient.getRelations(GetRelationsRequest.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relationName) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .setSubjectRelation(subjectRelation) + .setWithObjects(withObjects) + .setPage(buildPaginationRequest(pageSize, pageToken)) + .build()); + } + + @Override + public CheckPermissionResponse checkPermission(String objectType, String objectId, String subjectType, String subjectId, String permissionName, boolean trace) { + return readerClient.checkPermission(CheckPermissionRequest.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .setPermission(permissionName) + .setTrace(trace) + .build()); + } + + @Override + public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, boolean trace) { + return readerClient.checkRelation(CheckRelationRequest.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relationName) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .setTrace(trace) + .build()); + } + + @Override + public CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId, boolean trace) { + return readerClient.check(CheckRequest.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relationName) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .setTrace(trace) + .build()); + } + + @Override + public SetObjectResponse setObject(String type, String id, String displayName, Struct properties, String hash) { + Instant time = Instant.now(); + Timestamp timestamp = Timestamp.newBuilder().setSeconds(time.getEpochSecond()) + .setNanos(time.getNano()).build(); + + SetObjectRequest objRequest = SetObjectRequest.newBuilder().setObject( + Object.newBuilder() + .setType(type) + .setId(id) + .setDisplayName(displayName) + .setProperties(properties) + .setCreatedAt(timestamp) + .build() + ).build(); + + return writerClient.setObject(objRequest); + } + + @Override + public DeleteObjectResponse deleteObject(String type, String id, boolean withRelations) { + return writerClient.deleteObject(DeleteObjectRequest.newBuilder() + .setObjectType(type) + .setObjectId(id) + .setWithRelations(withRelations) + .build()); + } + + @Override + public SetRelationResponse setRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, String hash) { + Relation relation = Relation.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relationName) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .setSubjectRelation(subjectRelation) + .setEtag(hash) + .build(); + + return writerClient.setRelation(SetRelationRequest.newBuilder().setRelation(relation).build()); + } + + @Override + public DeleteRelationResponse deleteRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation) { + return writerClient.deleteRelation(DeleteRelationRequest.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relationName) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .setSubjectRelation(subjectRelation) + .build()); + } + + @Override + public GetManifestResponse getManifest() { + GetManifestRequest manifestRequest = GetManifestRequest.newBuilder().build(); + Iterator manifestResponses = modelClient.getManifest(manifestRequest); + + StringBuilder bodyBuilder = new StringBuilder(); + Metadata.Builder metadataBuilder = Metadata.newBuilder(); + + manifestResponses.forEachRemaining(manifestResponse -> { + if (!manifestResponse.getMetadata().getAllFields().isEmpty()) { + manifestResponse.getMetadata().getAllFields().forEach(metadataBuilder::setField); + } else if (!manifestResponse.getBody().getData().isEmpty()) { + bodyBuilder.append(manifestResponse.getBody().getData().toStringUtf8()); + } + }); + + + Body manifestBody = Body.newBuilder().setData(ByteString.copyFrom(bodyBuilder.toString().getBytes())).build(); + + return GetManifestResponse.newBuilder() + .setMetadata(metadataBuilder.build()) + .setBody(manifestBody) + .build(); + } + + @Override + public SetManifestRequest setManifest(String manifest) { + Body manifestBody = Body.newBuilder().setData(ByteString.copyFrom(manifest.getBytes())).build(); + + return SetManifestRequest.newBuilder() + .setBody(manifestBody) + .build(); + } + + @Override + public DeleteManifestRequest deleteManifest() { + return DeleteManifestRequest.newBuilder().build(); + } + class ObjectIdentifierList implements Iterable { + + private List objects; + + public ObjectIdentifierList(List objects) { + this.objects = objects; + } + + @Override + public Iterator iterator() { + return objects.iterator(); + } + + } + + + public static void main(String[] args) throws SSLException { + // create a channel that has the connection details + ManagedChannel channel = new ChannelBuilder() + .withHost("localhost") + .withPort(9292) + .withInsecure(true) + .build(); + + DirClientBuilder dirClientBuilder = new DirClientBuilder(channel); + DirectoryClient directoryClient = new DirectoryClient(dirClientBuilder); + +// GetObjectResponse getObjectResponse = directoryClient.getObject("user", "morty@the-citadel.com", false); +// GetManifestResponse getManifestResponse = directoryClient.getManifest(); + +// System.out.println(getObjectResponse.toString()); +// System.out.println(getManifestResponse.getBody().getData().toStringUtf8()); + + + List objects = List.of( + ObjectIdentifier.newBuilder() + .setObjectType("user") + .setObjectId("rick@the-citadel.com") + .build(), + ObjectIdentifier.newBuilder() + .setObjectType("user") + .setObjectId("morty@the-citadel.com") + .build()); + + GetObjectManyRequest getObjectManyRequest = directoryClient.getObjectManyRequest(objects); + System.out.println(getObjectManyRequest); + } + + -public interface DirectoryClient { - public GetObjectResponse getObject(String type, String id, boolean withRelations); - public GetObjectsResponse getObjects(String type, int pageSize, String pageToken); - public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, - String subjectId, String subjectRelation, boolean withObjects); - public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, - String subjectType, String subjectId, String subjectRelation, - boolean withObjects, int pageSize, String pageToken); - public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, - String subjectType, String subjectId, boolean trace); - public CheckPermissionResponse checkPermission(String objectType, String objectId, String relationName, - String subjectType, String subjectId, boolean trace); - - public CheckResponse check(String objectType, String objectId, String relationName, - String subjectType, String subjectId, boolean trace); - - public SetObjectResponse setObject(String type, String id, String displayName, Struct properties, String hash); - public DeleteObjectResponse deleteObject(String type, String id, boolean withRelations); - public SetRelationResponse setRelation(String objectType, String objectId, String relationName, - String subjectType, String subjectId, String subjectRelation, String hash); - public DeleteRelationResponse deleteRelation(String objectType, String objectId, String relationName, - String subjectType, String subjectId, String subjectRelation); } diff --git a/src/main/java/com/aserto/DirectoryClientExporter.java b/src/main/java/com/aserto/DirectoryClientExporter.java new file mode 100644 index 0000000..ed61b48 --- /dev/null +++ b/src/main/java/com/aserto/DirectoryClientExporter.java @@ -0,0 +1,4 @@ +package com.aserto; + +public interface DirectoryClientExporter { +} diff --git a/src/main/java/com/aserto/DirectoryClientImporter.java b/src/main/java/com/aserto/DirectoryClientImporter.java new file mode 100644 index 0000000..a97cd28 --- /dev/null +++ b/src/main/java/com/aserto/DirectoryClientImporter.java @@ -0,0 +1,4 @@ +package com.aserto; + +public interface DirectoryClientImporter { +} diff --git a/src/main/java/com/aserto/DirectoryClientManifest.java b/src/main/java/com/aserto/DirectoryClientManifest.java new file mode 100644 index 0000000..56d9267 --- /dev/null +++ b/src/main/java/com/aserto/DirectoryClientManifest.java @@ -0,0 +1,11 @@ +package com.aserto; + +import com.aserto.directory.model.v3.DeleteManifestRequest; +import com.aserto.directory.model.v3.GetManifestResponse; +import com.aserto.directory.model.v3.SetManifestRequest; + +public interface DirectoryClientManifest { + public GetManifestResponse getManifest(); + public SetManifestRequest setManifest(String manifest); + public DeleteManifestRequest deleteManifest(); +} diff --git a/src/main/java/com/aserto/DirectoryClientReader.java b/src/main/java/com/aserto/DirectoryClientReader.java new file mode 100644 index 0000000..3a35c4f --- /dev/null +++ b/src/main/java/com/aserto/DirectoryClientReader.java @@ -0,0 +1,20 @@ +package com.aserto; + +import com.aserto.directory.reader.v3.*; + +public interface DirectoryClientReader { + public GetObjectResponse getObject(String type, String id, boolean withRelations); + public GetObjectsResponse getObjects(String type, int pageSize, String pageToken); + public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, + String subjectId, String subjectRelation, boolean withObjects); + public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, + String subjectType, String subjectId, String subjectRelation, + boolean withObjects, int pageSize, String pageToken); + public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId, boolean trace); + public CheckPermissionResponse checkPermission(String objectType, String objectId, + String subjectType, String subjectId, String permissionName, boolean trace); + + public CheckResponse check(String objectType, String objectId, String relationName, + String subjectType, String subjectId, boolean trace); +} diff --git a/src/main/java/com/aserto/DirectoryClientWriter.java b/src/main/java/com/aserto/DirectoryClientWriter.java new file mode 100644 index 0000000..f8e8828 --- /dev/null +++ b/src/main/java/com/aserto/DirectoryClientWriter.java @@ -0,0 +1,16 @@ +package com.aserto; + +import com.aserto.directory.writer.v3.DeleteObjectResponse; +import com.aserto.directory.writer.v3.DeleteRelationResponse; +import com.aserto.directory.writer.v3.SetObjectResponse; +import com.aserto.directory.writer.v3.SetRelationResponse; +import com.google.protobuf.Struct; + +public interface DirectoryClientWriter { + public SetObjectResponse setObject(String type, String id, String displayName, Struct properties, String hash); + public DeleteObjectResponse deleteObject(String type, String id, boolean withRelations); + public SetRelationResponse setRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId, String subjectRelation, String hash); + public DeleteRelationResponse deleteRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId, String subjectRelation); +} diff --git a/src/test/java/DirClientTest.java b/src/test/java/DirectoryClientBuilderTest.java similarity index 58% rename from src/test/java/DirClientTest.java rename to src/test/java/DirectoryClientBuilderTest.java index 70f68b2..c92e096 100644 --- a/src/test/java/DirClientTest.java +++ b/src/test/java/DirectoryClientBuilderTest.java @@ -1,4 +1,4 @@ -import com.aserto.DirClient; +import com.aserto.DirClientBuilder; import io.grpc.ManagedChannel; import io.grpc.inprocess.InProcessChannelBuilder; import io.grpc.inprocess.InProcessServerBuilder; @@ -12,7 +12,7 @@ import static org.junit.jupiter.api.Assertions.*; -public class DirClientTest { +public class DirectoryClientBuilderTest { @Rule public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule(); @@ -31,24 +31,24 @@ public void setUp() throws IOException { @Test void createDirectoryClientWithReader() { // Arrange & Act - DirClient dirClient = new DirClient(channel, null, null, null); + DirClientBuilder dirClientBuilder = new DirClientBuilder(channel, null, null, null, null); // Assert - assertNotEquals(null, dirClient.getReaderClient()); - assertNull(dirClient.getWriterClient()); - assertNull(dirClient.getImporterClient()); - assertNull(dirClient.getExporterClient()); + assertNotEquals(null, dirClientBuilder.getReaderClient()); + assertNull(dirClientBuilder.getWriterClient()); + assertNull(dirClientBuilder.getImporterClient()); + assertNull(dirClientBuilder.getExporterClient()); } @Test void createDirectoryClientsWithSameChannel() { // Arrange & Act - DirClient dirClient = new DirClient(channel); + DirClientBuilder dirClientBuilder = new DirClientBuilder(channel); // Assert - assertNotEquals(null, dirClient.getReaderClient()); - assertNotEquals(null, dirClient.getWriterClient()); - assertNotEquals(null, dirClient.getImporterClient()); - assertNotEquals(null, dirClient.getExporterClient()); + assertNotEquals(null, dirClientBuilder.getReaderClient()); + assertNotEquals(null, dirClientBuilder.getWriterClient()); + assertNotEquals(null, dirClientBuilder.getImporterClient()); + assertNotEquals(null, dirClientBuilder.getExporterClient()); } } From 0a296d2817c44ef7cf076713e1126a8fbd4c77fa Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Thu, 16 Nov 2023 10:56:49 +0200 Subject: [PATCH 03/26] Add getGraph to the directory api. --- src/main/java/com/aserto/DirectoryClient.java | 47 ++++++++++++++----- .../com/aserto/DirectoryClientReader.java | 6 +++ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/aserto/DirectoryClient.java b/src/main/java/com/aserto/DirectoryClient.java index 853f8a1..2b2f0ca 100644 --- a/src/main/java/com/aserto/DirectoryClient.java +++ b/src/main/java/com/aserto/DirectoryClient.java @@ -52,6 +52,7 @@ public GetObjectsResponse getObjects(String type, int pageSize, String pageToken .build()); } + @Override public GetObjectManyRequest getObjectManyRequest(List objectIdentifiers) { return GetObjectManyRequest.newBuilder() .addAllParam(new ObjectIdentifierList(objectIdentifiers)) @@ -128,6 +129,21 @@ public CheckResponse check(String objectType, String objectId, String relationNa .build()); } + public GetGraphResponse getGraph(String anchorType, String anchorId, String objectType, String objectId, + String relation, String subjectType, String subjectId, String subjectRelation) { + + return readerClient.getGraph(GetGraphRequest.newBuilder() + .setAnchorType(anchorType) + .setAnchorId(anchorId) + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relation) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .setSubjectRelation(subjectRelation) + .build()); + } + @Override public SetObjectResponse setObject(String type, String id, String displayName, Struct properties, String hash) { Instant time = Instant.now(); @@ -221,8 +237,9 @@ public SetManifestRequest setManifest(String manifest) { public DeleteManifestRequest deleteManifest() { return DeleteManifestRequest.newBuilder().build(); } - class ObjectIdentifierList implements Iterable { + + private class ObjectIdentifierList implements Iterable { private List objects; public ObjectIdentifierList(List objects) { @@ -254,19 +271,25 @@ public static void main(String[] args) throws SSLException { // System.out.println(getObjectResponse.toString()); // System.out.println(getManifestResponse.getBody().getData().toStringUtf8()); +// --------------------------- +// List objects = List.of( +// ObjectIdentifier.newBuilder() +// .setObjectType("user") +// .setObjectId("rick@the-citadel.com") +// .build(), +// ObjectIdentifier.newBuilder() +// .setObjectType("user") +// .setObjectId("morty@the-citadel.com") +// .build()); +// +// GetObjectManyRequest getObjectManyRequest = directoryClient.getObjectManyRequest(objects); +// System.out.println(getObjectManyRequest); +// -------------------------------------- + + GetGraphResponse getGraphResponse = directoryClient.getGraph("user", "rick@the-citadel.com", "user", "rick@the-citadel.com","", "", "", ""); + System.out.println(getGraphResponse); - List objects = List.of( - ObjectIdentifier.newBuilder() - .setObjectType("user") - .setObjectId("rick@the-citadel.com") - .build(), - ObjectIdentifier.newBuilder() - .setObjectType("user") - .setObjectId("morty@the-citadel.com") - .build()); - GetObjectManyRequest getObjectManyRequest = directoryClient.getObjectManyRequest(objects); - System.out.println(getObjectManyRequest); } diff --git a/src/main/java/com/aserto/DirectoryClientReader.java b/src/main/java/com/aserto/DirectoryClientReader.java index 3a35c4f..db03748 100644 --- a/src/main/java/com/aserto/DirectoryClientReader.java +++ b/src/main/java/com/aserto/DirectoryClientReader.java @@ -1,10 +1,14 @@ package com.aserto; +import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.reader.v3.*; +import java.util.List; + public interface DirectoryClientReader { public GetObjectResponse getObject(String type, String id, boolean withRelations); public GetObjectsResponse getObjects(String type, int pageSize, String pageToken); + public GetObjectManyRequest getObjectManyRequest(List objectIdentifiers); public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects); public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, @@ -17,4 +21,6 @@ public CheckPermissionResponse checkPermission(String objectType, String objectI public CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId, boolean trace); + public GetGraphResponse getGraph(String anchorType, String anchorId, String objectType, String objectId, + String relation, String subjectType, String subjectId, String subjectRelation); } From 64064d6613fec5f9982bacc368432bb042a29bce Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Thu, 16 Nov 2023 14:40:28 +0200 Subject: [PATCH 04/26] Rename ClientManifest interface to ClientModel. --- .../java/com/aserto/DirectoryClientManifest.java | 11 ----------- src/main/java/com/aserto/DirectoryClientModel.java | 12 ++++++++++++ 2 files changed, 12 insertions(+), 11 deletions(-) delete mode 100644 src/main/java/com/aserto/DirectoryClientManifest.java create mode 100644 src/main/java/com/aserto/DirectoryClientModel.java diff --git a/src/main/java/com/aserto/DirectoryClientManifest.java b/src/main/java/com/aserto/DirectoryClientManifest.java deleted file mode 100644 index 56d9267..0000000 --- a/src/main/java/com/aserto/DirectoryClientManifest.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.aserto; - -import com.aserto.directory.model.v3.DeleteManifestRequest; -import com.aserto.directory.model.v3.GetManifestResponse; -import com.aserto.directory.model.v3.SetManifestRequest; - -public interface DirectoryClientManifest { - public GetManifestResponse getManifest(); - public SetManifestRequest setManifest(String manifest); - public DeleteManifestRequest deleteManifest(); -} diff --git a/src/main/java/com/aserto/DirectoryClientModel.java b/src/main/java/com/aserto/DirectoryClientModel.java new file mode 100644 index 0000000..a3d32a2 --- /dev/null +++ b/src/main/java/com/aserto/DirectoryClientModel.java @@ -0,0 +1,12 @@ +package com.aserto; + +import com.aserto.directory.model.v3.DeleteManifestResponse; +import com.aserto.directory.model.v3.GetManifestResponse; +import com.aserto.directory.model.v3.SetManifestRequest; +import com.aserto.directory.model.v3.SetManifestResponse; + +public interface DirectoryClientModel { + public GetManifestResponse getManifest(); + public SetManifestResponse setManifest(String manifest) throws InterruptedException; + public DeleteManifestResponse deleteManifest(); +} From 83b74605eeae36c84fbee4f69853071ee6bc8410 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Thu, 16 Nov 2023 14:41:56 +0200 Subject: [PATCH 05/26] Add async model client for setManifest --- pom.xml | 12 ++ .../java/com/aserto/DirClientBuilder.java | 7 ++ src/main/java/com/aserto/DirectoryClient.java | 104 ++++++++++++++++-- 3 files changed, 111 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 6a5cf67..c1e3072 100644 --- a/pom.xml +++ b/pom.xml @@ -83,6 +83,18 @@ 3.12.4 test + + + + org.apache.logging.log4j + log4j-api + 2.21.1 + + + org.apache.logging.log4j + log4j-core + 2.21.1 + diff --git a/src/main/java/com/aserto/DirClientBuilder.java b/src/main/java/com/aserto/DirClientBuilder.java index eeb12f4..085ce5e 100644 --- a/src/main/java/com/aserto/DirClientBuilder.java +++ b/src/main/java/com/aserto/DirClientBuilder.java @@ -17,6 +17,7 @@ public class DirClientBuilder { private ImporterGrpc.ImporterBlockingStub importerClient; private ExporterGrpc.ExporterBlockingStub exporterClient; private ModelGrpc.ModelBlockingStub modelClient; + private ModelGrpc.ModelStub modelClientAsync; private ManagedChannel channel; private ManagedChannel readerChannel; private ManagedChannel writerChannel; @@ -30,6 +31,7 @@ public DirClientBuilder(ManagedChannel channel) { this.importerClient = ImporterGrpc.newBlockingStub(channel); this.exporterClient = ExporterGrpc.newBlockingStub(channel); this.modelClient = ModelGrpc.newBlockingStub(channel); + this.modelClientAsync = ModelGrpc.newStub(channel); this.channel = channel; } @@ -61,6 +63,7 @@ public DirClientBuilder(ManagedChannel readerChannel, if (modelClient != null) { this.modelClient = ModelGrpc.newBlockingStub(modelChannel); + this.modelClientAsync = ModelGrpc.newStub(modelChannel); this.modelChannel = modelChannel; } } @@ -85,6 +88,10 @@ public ModelGrpc.ModelBlockingStub getModelClient() { return modelClient; } + public ModelGrpc.ModelStub getModelClientAsync() { + return modelClientAsync; + } + class Result { private T[] results; private String nextPageToken; diff --git a/src/main/java/com/aserto/DirectoryClient.java b/src/main/java/com/aserto/DirectoryClient.java index 2b2f0ca..f4ab889 100644 --- a/src/main/java/com/aserto/DirectoryClient.java +++ b/src/main/java/com/aserto/DirectoryClient.java @@ -4,6 +4,7 @@ import com.aserto.directory.common.v3.PaginationRequest; import com.aserto.directory.common.v3.Relation; import com.aserto.directory.exporter.v3.ExporterGrpc; +import com.aserto.directory.importer.v3.ImportRequest; import com.aserto.directory.importer.v3.ImporterGrpc; import com.aserto.directory.model.v3.*; import com.aserto.directory.reader.v3.*; @@ -15,23 +16,32 @@ import com.google.protobuf.Timestamp; import io.grpc.ManagedChannel; +import io.grpc.stub.StreamObserver; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import javax.net.ssl.SSLException; import java.time.Instant; import java.util.Iterator; import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; -public class DirectoryClient implements DirectoryClientReader, DirectoryClientWriter, DirectoryClientManifest { +public class DirectoryClient implements DirectoryClientReader, DirectoryClientWriter, DirectoryClientModel { + Logger logger = LogManager.getLogger(DirectoryClient.class); private ReaderGrpc.ReaderBlockingStub readerClient; private WriterGrpc.WriterBlockingStub writerClient; private ImporterGrpc.ImporterBlockingStub importerClient; private ExporterGrpc.ExporterBlockingStub exporterClient; private ModelGrpc.ModelBlockingStub modelClient; + private ModelGrpc.ModelStub modelClientAsync; public DirectoryClient(DirClientBuilder dirClientBuilder) { readerClient = dirClientBuilder.getReaderClient(); writerClient = dirClientBuilder.getWriterClient(); modelClient = dirClientBuilder.getModelClient(); + modelClientAsync = dirClientBuilder.getModelClientAsync(); } @@ -129,9 +139,9 @@ public CheckResponse check(String objectType, String objectId, String relationNa .build()); } + @Override public GetGraphResponse getGraph(String anchorType, String anchorId, String objectType, String objectId, String relation, String subjectType, String subjectId, String subjectRelation) { - return readerClient.getGraph(GetGraphRequest.newBuilder() .setAnchorType(anchorType) .setAnchorId(anchorId) @@ -225,19 +235,52 @@ public GetManifestResponse getManifest() { } @Override - public SetManifestRequest setManifest(String manifest) { + public SetManifestResponse setManifest(String manifest) throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + + StreamObserver readStream = new StreamObserver() { + @Override + public void onNext(SetManifestResponse setManifestResponse) { + logger.info("Received response: [{}] ", setManifestResponse.getResult()); + } + + @Override + public void onError(Throwable throwable) { + logger.error("Error from server: [{}]: ", throwable.getMessage()); + } + + @Override + public void onCompleted() { + logger.trace("Server completed stream."); + latch.countDown(); + } + }; + + Body manifestBody = Body.newBuilder().setData(ByteString.copyFrom(manifest.getBytes())).build(); - return SetManifestRequest.newBuilder() - .setBody(manifestBody) - .build(); + StreamObserver writeStream = modelClientAsync.setManifest(readStream); + writeStream.onNext(SetManifestRequest.newBuilder().setBody(manifestBody).build()); + writeStream.onCompleted(); + + boolean timedOut = !latch.await(5, TimeUnit.SECONDS); + if (timedOut) { + logger.error("Timed out waiting for server response."); + } + + return null; } @Override - public DeleteManifestRequest deleteManifest() { - return DeleteManifestRequest.newBuilder().build(); + public DeleteManifestResponse deleteManifest() { + return modelClient.deleteManifest(DeleteManifestRequest.newBuilder().build()); } +// public ImportRequest importData() { +// return importerClient. +// } + + private class ObjectIdentifierList implements Iterable { private List objects; @@ -254,7 +297,7 @@ public Iterator iterator() { } - public static void main(String[] args) throws SSLException { + public static void main(String[] args) throws SSLException, InterruptedException { // create a channel that has the connection details ManagedChannel channel = new ChannelBuilder() .withHost("localhost") @@ -267,7 +310,7 @@ public static void main(String[] args) throws SSLException { // GetObjectResponse getObjectResponse = directoryClient.getObject("user", "morty@the-citadel.com", false); // GetManifestResponse getManifestResponse = directoryClient.getManifest(); - +// // System.out.println(getObjectResponse.toString()); // System.out.println(getManifestResponse.getBody().getData().toStringUtf8()); @@ -286,8 +329,45 @@ public static void main(String[] args) throws SSLException { // System.out.println(getObjectManyRequest); // -------------------------------------- - GetGraphResponse getGraphResponse = directoryClient.getGraph("user", "rick@the-citadel.com", "user", "rick@the-citadel.com","", "", "", ""); - System.out.println(getGraphResponse); +// GetGraphResponse getGraphResponse = directoryClient.getGraph("user", "rick@the-citadel.com", "user", "rick@the-citadel.com","", "", "", ""); +// System.out.println(getGraphResponse); +// --------------------------------- + + +// String manifest = "# yaml-language-server: $schema=https://www.topaz.sh/schema/manifest.json\n" + +// "---\n" + +// "### model ###\n" + +// "model:\n" + +// " version: 3\n" + +// "\n" + +// "### object type definitions ###\n" + +// "types:\n" + +// " ### display_name: User ###\n" + +// " user:\n" + +// " relations:\n" + +// " ### display_name: user#manager ###\n" + +// " manager: user\n" + +// "\n" + +// " ### display_name: Identity ###\n" + +// " identity:\n" + +// " relations:\n" + +// " ### display_name: identity#identifier ###\n" + +// " identifier: user\n" + +// "\n" + +// " ### display_name: Group ###\n" + +// " group:\n" + +// " relations:\n" + +// " ### display_name: group#member ###\n" + +// " member: user"; +// +// directoryClient.setManifest(manifest); +// +// +// System.out.println(directoryClient.getManifest().getBody().getData().toStringUtf8()); + +// -------------------------------------- + + } From 10c39ffd810fe34f2ee251c516d05c9fa9bfd6c2 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Fri, 17 Nov 2023 13:40:34 +0200 Subject: [PATCH 06/26] Add message chunking to setManifest. --- .../java/com/aserto/DirClientBuilder.java | 35 +------ src/main/java/com/aserto/DirectoryClient.java | 92 +++++++++++-------- src/main/java/com/aserto/MessageChunker.java | 27 ++++++ 3 files changed, 85 insertions(+), 69 deletions(-) create mode 100644 src/main/java/com/aserto/MessageChunker.java diff --git a/src/main/java/com/aserto/DirClientBuilder.java b/src/main/java/com/aserto/DirClientBuilder.java index 085ce5e..f5e1b92 100644 --- a/src/main/java/com/aserto/DirClientBuilder.java +++ b/src/main/java/com/aserto/DirClientBuilder.java @@ -1,20 +1,16 @@ package com.aserto; -//import com.aserto.directory.common.v3.ObjectTypeIdentifier; -import com.aserto.directory.common.v2.ObjectTypeIdentifier; -import com.aserto.directory.common.v3.PaginationRequest; import com.aserto.directory.exporter.v3.ExporterGrpc; import com.aserto.directory.importer.v3.ImporterGrpc; import com.aserto.directory.model.v3.ModelGrpc; import com.aserto.directory.reader.v3.*; import com.aserto.directory.writer.v3.WriterGrpc; -import com.aserto.directory.common.v3.Object; import io.grpc.ManagedChannel; public class DirClientBuilder { private ReaderGrpc.ReaderBlockingStub readerClient; private WriterGrpc.WriterBlockingStub writerClient; - private ImporterGrpc.ImporterBlockingStub importerClient; + private ImporterGrpc.ImporterStub importerClient; private ExporterGrpc.ExporterBlockingStub exporterClient; private ModelGrpc.ModelBlockingStub modelClient; private ModelGrpc.ModelStub modelClientAsync; @@ -28,7 +24,7 @@ public class DirClientBuilder { public DirClientBuilder(ManagedChannel channel) { this.readerClient = ReaderGrpc.newBlockingStub(channel); this.writerClient = WriterGrpc.newBlockingStub(channel); - this.importerClient = ImporterGrpc.newBlockingStub(channel); + this.importerClient = ImporterGrpc.newStub(channel); this.exporterClient = ExporterGrpc.newBlockingStub(channel); this.modelClient = ModelGrpc.newBlockingStub(channel); this.modelClientAsync = ModelGrpc.newStub(channel); @@ -52,7 +48,7 @@ public DirClientBuilder(ManagedChannel readerChannel, } if (importerChannel != null) { - this.importerClient = ImporterGrpc.newBlockingStub(importerChannel); + this.importerClient = ImporterGrpc.newStub(importerChannel); this.importerChannel = importerChannel; } @@ -76,7 +72,7 @@ public WriterGrpc.WriterBlockingStub getWriterClient() { return writerClient; } - public ImporterGrpc.ImporterBlockingStub getImporterClient() { + public ImporterGrpc.ImporterStub getImporterClient() { return importerClient; } @@ -110,29 +106,6 @@ public String getNextPageToken() { } } -// public Result getObjects(String objectType, Integer pageSize, String nextPageToken) { -// GetObjectsRequest.Builder builder = GetObjectsRequest.newBuilder(); -// -// PaginationRequest paginationRequest = PaginationRequest.newBuilder() -// .setSize(pageSize) -// .setToken(nextPageToken) -// .build(); -// ObjectTypeIdentifier objectIdentifier = ObjectTypeIdentifier.newBuilder() -// .setName(objectType) -// .build(); -// -// GetObjectsRequest request = builder -// .setPage(paginationRequest) -// .setParam(objectIdentifier) -// .build(); -// GetObjectsResponse response = readerClient.getObjects(request); -// String nextToken = response.getPage().getNextToken(); -// -// -// Object[] objects = response.getResultsList().toArray(new Object[0]); -// return new Result<>(objects, nextToken); -// } - public void close() { if (channel != null) { channel.shutdown(); diff --git a/src/main/java/com/aserto/DirectoryClient.java b/src/main/java/com/aserto/DirectoryClient.java index f4ab889..dfcb9ae 100644 --- a/src/main/java/com/aserto/DirectoryClient.java +++ b/src/main/java/com/aserto/DirectoryClient.java @@ -22,13 +22,18 @@ import org.apache.logging.log4j.Logger; import javax.net.ssl.SSLException; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.time.Instant; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; public class DirectoryClient implements DirectoryClientReader, DirectoryClientWriter, DirectoryClientModel { + static final int MAX_CHUNK_SIZE = 65536; Logger logger = LogManager.getLogger(DirectoryClient.class); private ReaderGrpc.ReaderBlockingStub readerClient; private WriterGrpc.WriterBlockingStub writerClient; @@ -214,19 +219,24 @@ public GetManifestResponse getManifest() { GetManifestRequest manifestRequest = GetManifestRequest.newBuilder().build(); Iterator manifestResponses = modelClient.getManifest(manifestRequest); - StringBuilder bodyBuilder = new StringBuilder(); Metadata.Builder metadataBuilder = Metadata.newBuilder(); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); manifestResponses.forEachRemaining(manifestResponse -> { if (!manifestResponse.getMetadata().getAllFields().isEmpty()) { manifestResponse.getMetadata().getAllFields().forEach(metadataBuilder::setField); } else if (!manifestResponse.getBody().getData().isEmpty()) { - bodyBuilder.append(manifestResponse.getBody().getData().toStringUtf8()); + try { + outputStream.write(manifestResponse.getBody().getData().toByteArray()); + } catch (IOException e) { + logger.error("Could not write to stream the fallowing message: {}", manifestResponse.getBody().getData().toByteArray()); + throw new RuntimeException(e); + } } }); - - Body manifestBody = Body.newBuilder().setData(ByteString.copyFrom(bodyBuilder.toString().getBytes())).build(); + Body manifestBody = Body.newBuilder().setData(ByteString.copyFrom(outputStream.toByteArray())).build(); return GetManifestResponse.newBuilder() .setMetadata(metadataBuilder.build()) @@ -256,14 +266,19 @@ public void onCompleted() { } }; - - Body manifestBody = Body.newBuilder().setData(ByteString.copyFrom(manifest.getBytes())).build(); - StreamObserver writeStream = modelClientAsync.setManifest(readStream); - writeStream.onNext(SetManifestRequest.newBuilder().setBody(manifestBody).build()); + + MessageChunker chunker = new MessageChunker(MAX_CHUNK_SIZE, manifest.getBytes()); + while (chunker.hasNextChunk()) { + byte[] chunk = chunker.nextChunk(); + Body manifestBody = Body.newBuilder().setData(ByteString.copyFrom(chunk)).build(); + writeStream.onNext(SetManifestRequest.newBuilder().setBody(manifestBody).build()); + } + writeStream.onCompleted(); boolean timedOut = !latch.await(5, TimeUnit.SECONDS); + if (timedOut) { logger.error("Timed out waiting for server response."); } @@ -271,6 +286,7 @@ public void onCompleted() { return null; } + @Override public DeleteManifestResponse deleteManifest() { return modelClient.deleteManifest(DeleteManifestRequest.newBuilder().build()); @@ -334,36 +350,36 @@ public static void main(String[] args) throws SSLException, InterruptedException // --------------------------------- -// String manifest = "# yaml-language-server: $schema=https://www.topaz.sh/schema/manifest.json\n" + -// "---\n" + -// "### model ###\n" + -// "model:\n" + -// " version: 3\n" + -// "\n" + -// "### object type definitions ###\n" + -// "types:\n" + -// " ### display_name: User ###\n" + -// " user:\n" + -// " relations:\n" + -// " ### display_name: user#manager ###\n" + -// " manager: user\n" + -// "\n" + -// " ### display_name: Identity ###\n" + -// " identity:\n" + -// " relations:\n" + -// " ### display_name: identity#identifier ###\n" + -// " identifier: user\n" + -// "\n" + -// " ### display_name: Group ###\n" + -// " group:\n" + -// " relations:\n" + -// " ### display_name: group#member ###\n" + -// " member: user"; -// -// directoryClient.setManifest(manifest); -// -// -// System.out.println(directoryClient.getManifest().getBody().getData().toStringUtf8()); + String manifest = "# yaml-language-server: $schema=https://www.topaz.sh/schema/manifest.json\n" + + "---\n" + + "### model ###\n" + + "model:\n" + + " version: 3\n" + + "\n" + + "### object type definitions ###\n" + + "types:\n" + + " ### display_name: User ###\n" + + " user:\n" + + " relations:\n" + + " ### display_name: user#manager ###\n" + + " manager: user\n" + + "\n" + + " ### display_name: Identity ###\n" + + " identity:\n" + + " relations:\n" + + " ### display_name: identity#identifier ###\n" + + " identifier: user\n" + + "\n" + + " ### display_name: Group ###\n" + + " group:\n" + + " relations:\n" + + " ### display_name: group#member ###\n" + + " member: user"; + + directoryClient.setManifest(manifest); + + + System.out.println(directoryClient.getManifest().getBody().getData().toStringUtf8()); // -------------------------------------- diff --git a/src/main/java/com/aserto/MessageChunker.java b/src/main/java/com/aserto/MessageChunker.java new file mode 100644 index 0000000..6751237 --- /dev/null +++ b/src/main/java/com/aserto/MessageChunker.java @@ -0,0 +1,27 @@ +package com.aserto; + +public class MessageChunker { + private int maxChunkSize; + private byte[] message; + + private int chunkStart = 0; + + public MessageChunker(int maxChunkSize, byte[] message) { + this.maxChunkSize = maxChunkSize; + this.message = message; + } + + public byte[] nextChunk() { + int chunkEnd = Math.min(chunkStart + maxChunkSize, message.length); + + byte[] chunk = new byte[chunkEnd - chunkStart]; + System.arraycopy(message, chunkStart, chunk, 0, chunk.length); + chunkStart = chunkEnd; + return chunk; + } + + public boolean hasNextChunk() { + return chunkStart < message.length; + } + +} From 2ece1cf57c78ae2d3b86856a51667e1e6580972d Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Fri, 17 Nov 2023 17:04:11 +0200 Subject: [PATCH 07/26] Implement import and export interfaces, --- src/main/java/com/aserto/DirectoryClient.java | 172 +++++++++++++----- ...ilder.java => DirectoryClientBuilder.java} | 14 +- .../com/aserto/DirectoryClientExporter.java | 6 + .../com/aserto/DirectoryClientImporter.java | 4 + .../java/com/aserto/DirectoryClientModel.java | 4 +- .../java/com/aserto/model/ImportElement.java | 25 +++ src/test/java/DirectoryClientBuilderTest.java | 22 +-- 7 files changed, 177 insertions(+), 70 deletions(-) rename src/main/java/com/aserto/{DirClientBuilder.java => DirectoryClientBuilder.java} (91%) create mode 100644 src/main/java/com/aserto/model/ImportElement.java diff --git a/src/main/java/com/aserto/DirectoryClient.java b/src/main/java/com/aserto/DirectoryClient.java index dfcb9ae..e2bab8e 100644 --- a/src/main/java/com/aserto/DirectoryClient.java +++ b/src/main/java/com/aserto/DirectoryClient.java @@ -3,12 +3,17 @@ import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.common.v3.PaginationRequest; import com.aserto.directory.common.v3.Relation; +import com.aserto.directory.exporter.v3.ExportRequest; +import com.aserto.directory.exporter.v3.ExportResponse; import com.aserto.directory.exporter.v3.ExporterGrpc; +import com.aserto.directory.exporter.v3.Option; import com.aserto.directory.importer.v3.ImportRequest; +import com.aserto.directory.importer.v3.ImportResponse; import com.aserto.directory.importer.v3.ImporterGrpc; import com.aserto.directory.model.v3.*; import com.aserto.directory.reader.v3.*; import com.aserto.directory.writer.v3.*; +import com.aserto.model.ImportElement; import com.google.protobuf.ByteString; import com.google.protobuf.Struct; import com.aserto.directory.common.v3.Object; @@ -17,7 +22,6 @@ import com.google.protobuf.Timestamp; import io.grpc.ManagedChannel; import io.grpc.stub.StreamObserver; -import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -25,28 +29,32 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.time.Instant; -import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import java.util.stream.IntStream; +import java.util.stream.Stream; -public class DirectoryClient implements DirectoryClientReader, DirectoryClientWriter, DirectoryClientModel { +public class DirectoryClient implements DirectoryClientReader, + DirectoryClientWriter, + DirectoryClientModel, + DirectoryClientImporter { static final int MAX_CHUNK_SIZE = 65536; Logger logger = LogManager.getLogger(DirectoryClient.class); private ReaderGrpc.ReaderBlockingStub readerClient; private WriterGrpc.WriterBlockingStub writerClient; - private ImporterGrpc.ImporterBlockingStub importerClient; + private ImporterGrpc.ImporterStub importerClient; private ExporterGrpc.ExporterBlockingStub exporterClient; private ModelGrpc.ModelBlockingStub modelClient; private ModelGrpc.ModelStub modelClientAsync; - public DirectoryClient(DirClientBuilder dirClientBuilder) { - readerClient = dirClientBuilder.getReaderClient(); - writerClient = dirClientBuilder.getWriterClient(); - modelClient = dirClientBuilder.getModelClient(); - modelClientAsync = dirClientBuilder.getModelClientAsync(); + public DirectoryClient(DirectoryClientBuilder directoryClientBuilder) { + readerClient = directoryClientBuilder.getReaderClient(); + writerClient = directoryClientBuilder.getWriterClient(); + importerClient = directoryClientBuilder.getImporterClient(); + exporterClient = directoryClientBuilder.getExporterClient(); + modelClient = directoryClientBuilder.getModelClient(); + modelClientAsync = directoryClientBuilder.getModelClientAsync(); } @@ -245,7 +253,7 @@ public GetManifestResponse getManifest() { } @Override - public SetManifestResponse setManifest(String manifest) throws InterruptedException { + public void setManifest(String manifest) throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); StreamObserver readStream = new StreamObserver() { @@ -278,12 +286,9 @@ public void onCompleted() { writeStream.onCompleted(); boolean timedOut = !latch.await(5, TimeUnit.SECONDS); - if (timedOut) { logger.error("Timed out waiting for server response."); } - - return null; } @@ -292,9 +297,50 @@ public DeleteManifestResponse deleteManifest() { return modelClient.deleteManifest(DeleteManifestRequest.newBuilder().build()); } -// public ImportRequest importData() { -// return importerClient. -// } + @Override + public void importData(Stream importStream) throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + StreamObserver readStream = new StreamObserver() { + @Override + public void onNext(ImportResponse importResponse) { + logger.info("Received response: [{}] ", importResponse.getObject()); + } + + @Override + public void onError(Throwable throwable) { + logger.error("Error from server: [{}]: ", throwable.getMessage()); + } + + @Override + public void onCompleted() { + logger.trace("Server completed importStream."); + latch.countDown(); + } + }; + + StreamObserver writer = importerClient.import_(readStream); + + importStream.forEach(importElement -> { + if (importElement.getObject() != null) { + writer.onNext(ImportRequest.newBuilder().setObject(importElement.getObject()).build()); + } else if (importElement.getRelation() != null) { + writer.onNext(ImportRequest.newBuilder().setRelation(importElement.getRelation()).build()); + } + }); + writer.onCompleted(); + + boolean timedOut = !latch.await(5, TimeUnit.SECONDS); + if (timedOut) { + logger.error("Timed out waiting for server response."); + } + } + + public Iterator exportData(Option options, Timestamp startFrom) { + return exporterClient.export(ExportRequest.newBuilder() + .setOptions(options.getNumber()) + .setStartFrom(startFrom) + .build()); + } @@ -321,8 +367,8 @@ public static void main(String[] args) throws SSLException, InterruptedException .withInsecure(true) .build(); - DirClientBuilder dirClientBuilder = new DirClientBuilder(channel); - DirectoryClient directoryClient = new DirectoryClient(dirClientBuilder); + DirectoryClientBuilder directoryClientBuilder = new DirectoryClientBuilder(channel); + DirectoryClient directoryClient = new DirectoryClient(directoryClientBuilder); // GetObjectResponse getObjectResponse = directoryClient.getObject("user", "morty@the-citadel.com", false); // GetManifestResponse getManifestResponse = directoryClient.getManifest(); @@ -350,41 +396,69 @@ public static void main(String[] args) throws SSLException, InterruptedException // --------------------------------- - String manifest = "# yaml-language-server: $schema=https://www.topaz.sh/schema/manifest.json\n" + - "---\n" + - "### model ###\n" + - "model:\n" + - " version: 3\n" + - "\n" + - "### object type definitions ###\n" + - "types:\n" + - " ### display_name: User ###\n" + - " user:\n" + - " relations:\n" + - " ### display_name: user#manager ###\n" + - " manager: user\n" + - "\n" + - " ### display_name: Identity ###\n" + - " identity:\n" + - " relations:\n" + - " ### display_name: identity#identifier ###\n" + - " identifier: user\n" + - "\n" + - " ### display_name: Group ###\n" + - " group:\n" + - " relations:\n" + - " ### display_name: group#member ###\n" + - " member: user"; - - directoryClient.setManifest(manifest); - - - System.out.println(directoryClient.getManifest().getBody().getData().toStringUtf8()); +// String manifest = "# yaml-language-server: $schema=https://www.topaz.sh/schema/manifest.json\n" + +// "---\n" + +// "### model ###\n" + +// "model:\n" + +// " version: 3\n" + +// "\n" + +// "### object type definitions ###\n" + +// "types:\n" + +// " ### display_name: User ###\n" + +// " user:\n" + +// " relations:\n" + +// " ### display_name: user#manager ###\n" + +// " manager: user\n" + +// "\n" + +// " ### display_name: Identity ###\n" + +// " identity:\n" + +// " relations:\n" + +// " ### display_name: identity#identifier ###\n" + +// " identifier: user\n" + +// "\n" + +// " ### display_name: Group ###\n" + +// " group:\n" + +// " relations:\n" + +// " ### display_name: group#member ###\n" + +// " member: user"; +// +// directoryClient.setManifest(manifest); +// +// +// System.out.println(directoryClient.getManifest().getBody().getData().toStringUtf8()); // -------------------------------------- +// List list = new ArrayList<>(); +// Object user = Object.newBuilder() +// .setType("user") +// .setId("test@aserto.com").build(); +// Relation managerRelation = Relation.newBuilder() +// .setObjectType("user") +// .setObjectId("test@aserto.com") +// .setRelation("manager") +// .setSubjectType("user") +// .setSubjectId("morty@the-citadel.com") +// .build(); +// +// list.add(new ImportElement(user)); +// list.add(new ImportElement(managerRelation)); +// +// directoryClient.importData(list.stream()); +// +// +// directoryClient.getObjects("user", 10, ""); +// directoryClient.getObject("user", "test@aserto.com", true); + +// --------------------------------------- +// directoryClient.setObject("user", "test", "test", Struct.newBuilder().build(), ""); + +// ----------------------------------- + Iterator exportedData = directoryClient.exportData( Option.OPTION_DATA, Timestamp.newBuilder().setSeconds(0).setNanos(0).build()); + exportedData.forEachRemaining(System.out::println); +// ----------------------------------- } diff --git a/src/main/java/com/aserto/DirClientBuilder.java b/src/main/java/com/aserto/DirectoryClientBuilder.java similarity index 91% rename from src/main/java/com/aserto/DirClientBuilder.java rename to src/main/java/com/aserto/DirectoryClientBuilder.java index f5e1b92..e45c7bd 100644 --- a/src/main/java/com/aserto/DirClientBuilder.java +++ b/src/main/java/com/aserto/DirectoryClientBuilder.java @@ -7,7 +7,7 @@ import com.aserto.directory.writer.v3.WriterGrpc; import io.grpc.ManagedChannel; -public class DirClientBuilder { +public class DirectoryClientBuilder { private ReaderGrpc.ReaderBlockingStub readerClient; private WriterGrpc.WriterBlockingStub writerClient; private ImporterGrpc.ImporterStub importerClient; @@ -21,7 +21,7 @@ public class DirClientBuilder { private ManagedChannel exporterChannel; private ManagedChannel modelChannel; - public DirClientBuilder(ManagedChannel channel) { + public DirectoryClientBuilder(ManagedChannel channel) { this.readerClient = ReaderGrpc.newBlockingStub(channel); this.writerClient = WriterGrpc.newBlockingStub(channel); this.importerClient = ImporterGrpc.newStub(channel); @@ -31,11 +31,11 @@ public DirClientBuilder(ManagedChannel channel) { this.channel = channel; } - public DirClientBuilder(ManagedChannel readerChannel, - ManagedChannel writerChannel, - ManagedChannel importerChannel, - ManagedChannel exporterChannel, - ManagedChannel modelChannel) { + public DirectoryClientBuilder(ManagedChannel readerChannel, + ManagedChannel writerChannel, + ManagedChannel importerChannel, + ManagedChannel exporterChannel, + ManagedChannel modelChannel) { if (readerChannel != null) { this.readerClient = ReaderGrpc.newBlockingStub(readerChannel); diff --git a/src/main/java/com/aserto/DirectoryClientExporter.java b/src/main/java/com/aserto/DirectoryClientExporter.java index ed61b48..0596b24 100644 --- a/src/main/java/com/aserto/DirectoryClientExporter.java +++ b/src/main/java/com/aserto/DirectoryClientExporter.java @@ -1,4 +1,10 @@ package com.aserto; +import com.aserto.directory.exporter.v3.ExportResponse; +import com.google.protobuf.Timestamp; + +import java.util.Iterator; + public interface DirectoryClientExporter { + Iterator exportData(int options, Timestamp startFrom); } diff --git a/src/main/java/com/aserto/DirectoryClientImporter.java b/src/main/java/com/aserto/DirectoryClientImporter.java index a97cd28..879f5a6 100644 --- a/src/main/java/com/aserto/DirectoryClientImporter.java +++ b/src/main/java/com/aserto/DirectoryClientImporter.java @@ -1,4 +1,8 @@ package com.aserto; +import com.aserto.model.ImportElement; +import java.util.stream.Stream; + public interface DirectoryClientImporter { + void importData(Stream importStream) throws InterruptedException; } diff --git a/src/main/java/com/aserto/DirectoryClientModel.java b/src/main/java/com/aserto/DirectoryClientModel.java index a3d32a2..e3454cd 100644 --- a/src/main/java/com/aserto/DirectoryClientModel.java +++ b/src/main/java/com/aserto/DirectoryClientModel.java @@ -2,11 +2,9 @@ import com.aserto.directory.model.v3.DeleteManifestResponse; import com.aserto.directory.model.v3.GetManifestResponse; -import com.aserto.directory.model.v3.SetManifestRequest; -import com.aserto.directory.model.v3.SetManifestResponse; public interface DirectoryClientModel { public GetManifestResponse getManifest(); - public SetManifestResponse setManifest(String manifest) throws InterruptedException; + public void setManifest(String manifest) throws InterruptedException; public DeleteManifestResponse deleteManifest(); } diff --git a/src/main/java/com/aserto/model/ImportElement.java b/src/main/java/com/aserto/model/ImportElement.java new file mode 100644 index 0000000..5531ce7 --- /dev/null +++ b/src/main/java/com/aserto/model/ImportElement.java @@ -0,0 +1,25 @@ +package com.aserto.model; + +import com.aserto.directory.common.v3.Object; +import com.aserto.directory.common.v3.Relation; + +public class ImportElement { + private Object object; + private Relation relation; + + public ImportElement(Object object) { + this.object = object; + } + + public ImportElement(Relation relation){ + this.relation = relation; + } + + public Object getObject() { + return object; + } + + public Relation getRelation() { + return relation; + } +} diff --git a/src/test/java/DirectoryClientBuilderTest.java b/src/test/java/DirectoryClientBuilderTest.java index c92e096..46c5242 100644 --- a/src/test/java/DirectoryClientBuilderTest.java +++ b/src/test/java/DirectoryClientBuilderTest.java @@ -1,4 +1,4 @@ -import com.aserto.DirClientBuilder; +import com.aserto.DirectoryClientBuilder; import io.grpc.ManagedChannel; import io.grpc.inprocess.InProcessChannelBuilder; import io.grpc.inprocess.InProcessServerBuilder; @@ -31,24 +31,24 @@ public void setUp() throws IOException { @Test void createDirectoryClientWithReader() { // Arrange & Act - DirClientBuilder dirClientBuilder = new DirClientBuilder(channel, null, null, null, null); + DirectoryClientBuilder directoryClientBuilder = new DirectoryClientBuilder(channel, null, null, null, null); // Assert - assertNotEquals(null, dirClientBuilder.getReaderClient()); - assertNull(dirClientBuilder.getWriterClient()); - assertNull(dirClientBuilder.getImporterClient()); - assertNull(dirClientBuilder.getExporterClient()); + assertNotEquals(null, directoryClientBuilder.getReaderClient()); + assertNull(directoryClientBuilder.getWriterClient()); + assertNull(directoryClientBuilder.getImporterClient()); + assertNull(directoryClientBuilder.getExporterClient()); } @Test void createDirectoryClientsWithSameChannel() { // Arrange & Act - DirClientBuilder dirClientBuilder = new DirClientBuilder(channel); + DirectoryClientBuilder directoryClientBuilder = new DirectoryClientBuilder(channel); // Assert - assertNotEquals(null, dirClientBuilder.getReaderClient()); - assertNotEquals(null, dirClientBuilder.getWriterClient()); - assertNotEquals(null, dirClientBuilder.getImporterClient()); - assertNotEquals(null, dirClientBuilder.getExporterClient()); + assertNotEquals(null, directoryClientBuilder.getReaderClient()); + assertNotEquals(null, directoryClientBuilder.getWriterClient()); + assertNotEquals(null, directoryClientBuilder.getImporterClient()); + assertNotEquals(null, directoryClientBuilder.getExporterClient()); } } From 06cec082e46f45e6dc04f2eb09e99c38b46bdf25 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Sun, 19 Nov 2023 13:16:32 +0200 Subject: [PATCH 08/26] Add authorizer and directory packages --- src/main/java/com/aserto/{ => authorizer}/AuthzClient.java | 3 ++- src/main/java/com/aserto/{ => directory}/DirectoryClient.java | 4 +++- .../com/aserto/{ => directory}/DirectoryClientBuilder.java | 2 +- .../com/aserto/{ => directory}/DirectoryClientExporter.java | 2 +- .../com/aserto/{ => directory}/DirectoryClientImporter.java | 2 +- .../java/com/aserto/{ => directory}/DirectoryClientModel.java | 2 +- .../com/aserto/{ => directory}/DirectoryClientReader.java | 2 +- .../com/aserto/{ => directory}/DirectoryClientWriter.java | 2 +- src/main/java/com/aserto/{ => utils}/MessageChunker.java | 3 ++- src/test/java/AuthzClientIntegrationTest.java | 2 +- src/test/java/AuthzClientTest.java | 2 +- src/test/java/DirectoryClientBuilderTest.java | 2 +- 12 files changed, 16 insertions(+), 12 deletions(-) rename src/main/java/com/aserto/{ => authorizer}/AuthzClient.java (98%) rename src/main/java/com/aserto/{ => directory}/DirectoryClient.java (99%) rename src/main/java/com/aserto/{ => directory}/DirectoryClientBuilder.java (99%) rename src/main/java/com/aserto/{ => directory}/DirectoryClientExporter.java (89%) rename src/main/java/com/aserto/{ => directory}/DirectoryClientImporter.java (87%) rename src/main/java/com/aserto/{ => directory}/DirectoryClientModel.java (91%) rename src/main/java/com/aserto/{ => directory}/DirectoryClientReader.java (98%) rename src/main/java/com/aserto/{ => directory}/DirectoryClientWriter.java (96%) rename src/main/java/com/aserto/{ => utils}/MessageChunker.java (90%) diff --git a/src/main/java/com/aserto/AuthzClient.java b/src/main/java/com/aserto/authorizer/AuthzClient.java similarity index 98% rename from src/main/java/com/aserto/AuthzClient.java rename to src/main/java/com/aserto/authorizer/AuthzClient.java index e67c85b..3c57a2c 100644 --- a/src/main/java/com/aserto/AuthzClient.java +++ b/src/main/java/com/aserto/authorizer/AuthzClient.java @@ -1,5 +1,6 @@ -package com.aserto; +package com.aserto.authorizer; +import com.aserto.AuthorizerClient; import com.aserto.authorizer.v2.*; import com.aserto.authorizer.v2.Decision; import com.aserto.authorizer.v2.api.*; diff --git a/src/main/java/com/aserto/DirectoryClient.java b/src/main/java/com/aserto/directory/DirectoryClient.java similarity index 99% rename from src/main/java/com/aserto/DirectoryClient.java rename to src/main/java/com/aserto/directory/DirectoryClient.java index e2bab8e..8bd6a52 100644 --- a/src/main/java/com/aserto/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/DirectoryClient.java @@ -1,5 +1,7 @@ -package com.aserto; +package com.aserto.directory; +import com.aserto.ChannelBuilder; +import com.aserto.utils.MessageChunker; import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.common.v3.PaginationRequest; import com.aserto.directory.common.v3.Relation; diff --git a/src/main/java/com/aserto/DirectoryClientBuilder.java b/src/main/java/com/aserto/directory/DirectoryClientBuilder.java similarity index 99% rename from src/main/java/com/aserto/DirectoryClientBuilder.java rename to src/main/java/com/aserto/directory/DirectoryClientBuilder.java index e45c7bd..41820fe 100644 --- a/src/main/java/com/aserto/DirectoryClientBuilder.java +++ b/src/main/java/com/aserto/directory/DirectoryClientBuilder.java @@ -1,4 +1,4 @@ -package com.aserto; +package com.aserto.directory; import com.aserto.directory.exporter.v3.ExporterGrpc; import com.aserto.directory.importer.v3.ImporterGrpc; diff --git a/src/main/java/com/aserto/DirectoryClientExporter.java b/src/main/java/com/aserto/directory/DirectoryClientExporter.java similarity index 89% rename from src/main/java/com/aserto/DirectoryClientExporter.java rename to src/main/java/com/aserto/directory/DirectoryClientExporter.java index 0596b24..1759f22 100644 --- a/src/main/java/com/aserto/DirectoryClientExporter.java +++ b/src/main/java/com/aserto/directory/DirectoryClientExporter.java @@ -1,4 +1,4 @@ -package com.aserto; +package com.aserto.directory; import com.aserto.directory.exporter.v3.ExportResponse; import com.google.protobuf.Timestamp; diff --git a/src/main/java/com/aserto/DirectoryClientImporter.java b/src/main/java/com/aserto/directory/DirectoryClientImporter.java similarity index 87% rename from src/main/java/com/aserto/DirectoryClientImporter.java rename to src/main/java/com/aserto/directory/DirectoryClientImporter.java index 879f5a6..54af1e3 100644 --- a/src/main/java/com/aserto/DirectoryClientImporter.java +++ b/src/main/java/com/aserto/directory/DirectoryClientImporter.java @@ -1,4 +1,4 @@ -package com.aserto; +package com.aserto.directory; import com.aserto.model.ImportElement; import java.util.stream.Stream; diff --git a/src/main/java/com/aserto/DirectoryClientModel.java b/src/main/java/com/aserto/directory/DirectoryClientModel.java similarity index 91% rename from src/main/java/com/aserto/DirectoryClientModel.java rename to src/main/java/com/aserto/directory/DirectoryClientModel.java index e3454cd..96a9725 100644 --- a/src/main/java/com/aserto/DirectoryClientModel.java +++ b/src/main/java/com/aserto/directory/DirectoryClientModel.java @@ -1,4 +1,4 @@ -package com.aserto; +package com.aserto.directory; import com.aserto.directory.model.v3.DeleteManifestResponse; import com.aserto.directory.model.v3.GetManifestResponse; diff --git a/src/main/java/com/aserto/DirectoryClientReader.java b/src/main/java/com/aserto/directory/DirectoryClientReader.java similarity index 98% rename from src/main/java/com/aserto/DirectoryClientReader.java rename to src/main/java/com/aserto/directory/DirectoryClientReader.java index db03748..3888e13 100644 --- a/src/main/java/com/aserto/DirectoryClientReader.java +++ b/src/main/java/com/aserto/directory/DirectoryClientReader.java @@ -1,4 +1,4 @@ -package com.aserto; +package com.aserto.directory; import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.reader.v3.*; diff --git a/src/main/java/com/aserto/DirectoryClientWriter.java b/src/main/java/com/aserto/directory/DirectoryClientWriter.java similarity index 96% rename from src/main/java/com/aserto/DirectoryClientWriter.java rename to src/main/java/com/aserto/directory/DirectoryClientWriter.java index f8e8828..99ddcb8 100644 --- a/src/main/java/com/aserto/DirectoryClientWriter.java +++ b/src/main/java/com/aserto/directory/DirectoryClientWriter.java @@ -1,4 +1,4 @@ -package com.aserto; +package com.aserto.directory; import com.aserto.directory.writer.v3.DeleteObjectResponse; import com.aserto.directory.writer.v3.DeleteRelationResponse; diff --git a/src/main/java/com/aserto/MessageChunker.java b/src/main/java/com/aserto/utils/MessageChunker.java similarity index 90% rename from src/main/java/com/aserto/MessageChunker.java rename to src/main/java/com/aserto/utils/MessageChunker.java index 6751237..17bca84 100644 --- a/src/main/java/com/aserto/MessageChunker.java +++ b/src/main/java/com/aserto/utils/MessageChunker.java @@ -1,5 +1,6 @@ -package com.aserto; +package com.aserto.utils; +/* Chunk messages into smaller pieces. */ public class MessageChunker { private int maxChunkSize; private byte[] message; diff --git a/src/test/java/AuthzClientIntegrationTest.java b/src/test/java/AuthzClientIntegrationTest.java index a95ef08..40de99f 100644 --- a/src/test/java/AuthzClientIntegrationTest.java +++ b/src/test/java/AuthzClientIntegrationTest.java @@ -1,4 +1,4 @@ -import com.aserto.AuthzClient; +import com.aserto.authorizer.AuthzClient; import com.aserto.ChannelBuilder; import com.aserto.authorizer.v2.api.Module; import io.grpc.ManagedChannel; diff --git a/src/test/java/AuthzClientTest.java b/src/test/java/AuthzClientTest.java index 983f1ee..f61c571 100644 --- a/src/test/java/AuthzClientTest.java +++ b/src/test/java/AuthzClientTest.java @@ -1,5 +1,5 @@ import com.aserto.AuthorizerClient; -import com.aserto.AuthzClient; +import com.aserto.authorizer.AuthzClient; import com.aserto.authorizer.v2.*; import com.aserto.authorizer.v2.api.IdentityType; import com.aserto.authorizer.v2.api.Module; diff --git a/src/test/java/DirectoryClientBuilderTest.java b/src/test/java/DirectoryClientBuilderTest.java index 46c5242..9f25480 100644 --- a/src/test/java/DirectoryClientBuilderTest.java +++ b/src/test/java/DirectoryClientBuilderTest.java @@ -1,4 +1,4 @@ -import com.aserto.DirectoryClientBuilder; +import com.aserto.directory.DirectoryClientBuilder; import io.grpc.ManagedChannel; import io.grpc.inprocess.InProcessChannelBuilder; import io.grpc.inprocess.InProcessServerBuilder; From 888c91531d00b19d90d7ae5bf0ce0431b6198a83 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Sun, 19 Nov 2023 13:16:56 +0200 Subject: [PATCH 09/26] Add directory client example skeleton project. --- examples/directory-example/.gitignore | 38 +++++++++++++ examples/directory-example/pom.xml | 54 +++++++++++++++++++ .../java/org/example/DirectoryExample.java | 7 +++ 3 files changed, 99 insertions(+) create mode 100644 examples/directory-example/.gitignore create mode 100644 examples/directory-example/pom.xml create mode 100644 examples/directory-example/src/main/java/org/example/DirectoryExample.java diff --git a/examples/directory-example/.gitignore b/examples/directory-example/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/examples/directory-example/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/examples/directory-example/pom.xml b/examples/directory-example/pom.xml new file mode 100644 index 0000000..38c91ab --- /dev/null +++ b/examples/directory-example/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + org.example + directory-example + 0.0.1 + + + 17 + 17 + UTF-8 + + + + + com.aserto + aserto-java + 0.20.9 + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + false + + + + + shade + + + true + + + + + org.example.DirectoryExample + + + + + + + + + \ No newline at end of file diff --git a/examples/directory-example/src/main/java/org/example/DirectoryExample.java b/examples/directory-example/src/main/java/org/example/DirectoryExample.java new file mode 100644 index 0000000..3f66f4f --- /dev/null +++ b/examples/directory-example/src/main/java/org/example/DirectoryExample.java @@ -0,0 +1,7 @@ +package org.example; + +public class DirectoryExample { + public static void main(String[] args) { + System.out.println("Hello world!"); + } +} \ No newline at end of file From 2a2a9c38fdab6b18b691758250d1912833c98670 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Mon, 20 Nov 2023 13:34:52 +0200 Subject: [PATCH 10/26] Make ObjectIdentifierList a standalone class. Update interfaces with optional field to make the java api similar to the proto definitions. --- examples/directory-example/pom.xml | 2 +- pom.xml | 2 +- .../com/aserto/directory/DirectoryClient.java | 88 +++++++++++++------ .../directory/DirectoryClientReader.java | 15 +++- .../directory/DirectoryClientWriter.java | 3 + .../directory/ObjectIdentifierList.java | 19 ++++ 6 files changed, 99 insertions(+), 30 deletions(-) create mode 100644 src/main/java/com/aserto/directory/ObjectIdentifierList.java diff --git a/examples/directory-example/pom.xml b/examples/directory-example/pom.xml index 38c91ab..1c9e8fe 100644 --- a/examples/directory-example/pom.xml +++ b/examples/directory-example/pom.xml @@ -18,7 +18,7 @@ com.aserto aserto-java - 0.20.9 + 0.20.10 diff --git a/pom.xml b/pom.xml index c1e3072..8724f79 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.aserto aserto-java - 0.20.9 + 0.20.10 ${project.groupId}:${project.artifactId} Java SDK to interact with aserto services diff --git a/src/main/java/com/aserto/directory/DirectoryClient.java b/src/main/java/com/aserto/directory/DirectoryClient.java index 8bd6a52..0190df6 100644 --- a/src/main/java/com/aserto/directory/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/DirectoryClient.java @@ -50,16 +50,22 @@ public class DirectoryClient implements DirectoryClientReader, private ModelGrpc.ModelBlockingStub modelClient; private ModelGrpc.ModelStub modelClientAsync; - public DirectoryClient(DirectoryClientBuilder directoryClientBuilder) { - readerClient = directoryClientBuilder.getReaderClient(); - writerClient = directoryClientBuilder.getWriterClient(); - importerClient = directoryClientBuilder.getImporterClient(); - exporterClient = directoryClientBuilder.getExporterClient(); - modelClient = directoryClientBuilder.getModelClient(); - modelClientAsync = directoryClientBuilder.getModelClientAsync(); + public DirectoryClient(ManagedChannel channelBuilder) { + DirectoryClientBuilder dirClientBuilder = new DirectoryClientBuilder(channelBuilder); + readerClient = dirClientBuilder.getReaderClient(); + writerClient = dirClientBuilder.getWriterClient(); + importerClient = dirClientBuilder.getImporterClient(); + exporterClient = dirClientBuilder.getExporterClient(); + modelClient = dirClientBuilder.getModelClient(); + modelClientAsync = dirClientBuilder.getModelClientAsync(); } + + @Override + public GetObjectResponse getObject(String type, String id) { + return getObject(type, id, false); + } @Override public GetObjectResponse getObject(String type, String id, boolean withRelations) { return readerClient.getObject(GetObjectRequest.newBuilder() @@ -69,6 +75,11 @@ public GetObjectResponse getObject(String type, String id, boolean withRelations .build()); } + @Override + public GetObjectsResponse getObjects(String type) { + return getObjects(type, 100, ""); + } + @Override public GetObjectsResponse getObjects(String type, int pageSize, String pageToken) { return readerClient.getObjects(GetObjectsRequest.newBuilder() @@ -91,6 +102,11 @@ private PaginationRequest buildPaginationRequest(int pageSize, String pageToken) .build(); } + + @Override + public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation) { + return getRelation(objectType, objectId, relationName, subjectType, subjectId, subjectRelation, false); + } @Override public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects) { return readerClient.getRelation(GetRelationRequest.newBuilder() @@ -104,6 +120,11 @@ public GetRelationResponse getRelation(String objectType, String objectId, Strin .build()); } + @Override + public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects) { + return getRelations(objectType, objectId, relationName, subjectType, subjectId, subjectRelation, withObjects, 100, ""); + } + @Override public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects, int pageSize, String pageToken) { return readerClient.getRelations(GetRelationsRequest.newBuilder() @@ -118,6 +139,11 @@ public GetRelationsResponse getRelations(String objectType, String objectId, Str .build()); } + @Override + public CheckPermissionResponse checkPermission(String objectType, String objectId, String subjectType, String subjectId, String permissionName) { + return checkPermission(objectType, objectId, subjectType, subjectId, permissionName, false); + } + @Override public CheckPermissionResponse checkPermission(String objectType, String objectId, String subjectType, String subjectId, String permissionName, boolean trace) { return readerClient.checkPermission(CheckPermissionRequest.newBuilder() @@ -130,6 +156,11 @@ public CheckPermissionResponse checkPermission(String objectType, String objectI .build()); } + @Override + public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId) { + return checkRelation(objectType, objectId, relationName, subjectType, subjectId, false); + } + @Override public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, boolean trace) { return readerClient.checkRelation(CheckRelationRequest.newBuilder() @@ -142,6 +173,11 @@ public CheckRelationResponse checkRelation(String objectType, String objectId, S .build()); } + @Override + public CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId) { + return check(objectType, objectId, relationName, subjectType, subjectId, false); + } + @Override public CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId, boolean trace) { return readerClient.check(CheckRequest.newBuilder() @@ -188,6 +224,11 @@ public SetObjectResponse setObject(String type, String id, String displayName, S return writerClient.setObject(objRequest); } + @Override + public DeleteObjectResponse deleteObject(String type, String id) { + return deleteObject(type, id, false); + } + @Override public DeleteObjectResponse deleteObject(String type, String id, boolean withRelations) { return writerClient.deleteObject(DeleteObjectRequest.newBuilder() @@ -197,6 +238,20 @@ public DeleteObjectResponse deleteObject(String type, String id, boolean withRel .build()); } + @Override + public SetRelationResponse setRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation) { + Relation relation = Relation.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relationName) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .setSubjectRelation(subjectRelation) + .build(); + + return writerClient.setRelation(SetRelationRequest.newBuilder().setRelation(relation).build()); + } + @Override public SetRelationResponse setRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, String hash) { Relation relation = Relation.newBuilder() @@ -345,22 +400,6 @@ public Iterator exportData(Option options, Timestamp startFrom) } - - private class ObjectIdentifierList implements Iterable { - private List objects; - - public ObjectIdentifierList(List objects) { - this.objects = objects; - } - - @Override - public Iterator iterator() { - return objects.iterator(); - } - - } - - public static void main(String[] args) throws SSLException, InterruptedException { // create a channel that has the connection details ManagedChannel channel = new ChannelBuilder() @@ -369,8 +408,7 @@ public static void main(String[] args) throws SSLException, InterruptedException .withInsecure(true) .build(); - DirectoryClientBuilder directoryClientBuilder = new DirectoryClientBuilder(channel); - DirectoryClient directoryClient = new DirectoryClient(directoryClientBuilder); + DirectoryClient directoryClient = new DirectoryClient(channel); // GetObjectResponse getObjectResponse = directoryClient.getObject("user", "morty@the-citadel.com", false); // GetManifestResponse getManifestResponse = directoryClient.getManifest(); diff --git a/src/main/java/com/aserto/directory/DirectoryClientReader.java b/src/main/java/com/aserto/directory/DirectoryClientReader.java index 3888e13..e20d605 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientReader.java +++ b/src/main/java/com/aserto/directory/DirectoryClientReader.java @@ -6,19 +6,28 @@ import java.util.List; public interface DirectoryClientReader { + public GetObjectResponse getObject(String type, String id); public GetObjectResponse getObject(String type, String id, boolean withRelations); + public GetObjectsResponse getObjects(String type); public GetObjectsResponse getObjects(String type, int pageSize, String pageToken); public GetObjectManyRequest getObjectManyRequest(List objectIdentifiers); + public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, + String subjectId, String subjectRelation); public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects); + public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, + String subjectType, String subjectId, String subjectRelation, boolean withObjects); public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects, int pageSize, String pageToken); - public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, - String subjectType, String subjectId, boolean trace); + public CheckPermissionResponse checkPermission(String objectType, String objectId, String subjectType, + String subjectId, String permissionName); public CheckPermissionResponse checkPermission(String objectType, String objectId, String subjectType, String subjectId, String permissionName, boolean trace); - + public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId); + public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId, boolean trace); + public CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId); public CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId, boolean trace); public GetGraphResponse getGraph(String anchorType, String anchorId, String objectType, String objectId, diff --git a/src/main/java/com/aserto/directory/DirectoryClientWriter.java b/src/main/java/com/aserto/directory/DirectoryClientWriter.java index 99ddcb8..51151b0 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientWriter.java +++ b/src/main/java/com/aserto/directory/DirectoryClientWriter.java @@ -8,7 +8,10 @@ public interface DirectoryClientWriter { public SetObjectResponse setObject(String type, String id, String displayName, Struct properties, String hash); + public DeleteObjectResponse deleteObject(String type, String id); public DeleteObjectResponse deleteObject(String type, String id, boolean withRelations); + public SetRelationResponse setRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId, String subjectRelation); public SetRelationResponse setRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, String hash); public DeleteRelationResponse deleteRelation(String objectType, String objectId, String relationName, diff --git a/src/main/java/com/aserto/directory/ObjectIdentifierList.java b/src/main/java/com/aserto/directory/ObjectIdentifierList.java new file mode 100644 index 0000000..bd8dc26 --- /dev/null +++ b/src/main/java/com/aserto/directory/ObjectIdentifierList.java @@ -0,0 +1,19 @@ +package com.aserto.directory; + +import com.aserto.directory.common.v3.ObjectIdentifier; + +import java.util.Iterator; +import java.util.List; + +class ObjectIdentifierList implements Iterable { + private List objects; + + public ObjectIdentifierList(List objects) { + this.objects = objects; + } + + @Override + public Iterator iterator() { + return objects.iterator(); + } +} From 7f5436a4ab1efe2f61394232bf5f911d154576e8 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Mon, 20 Nov 2023 13:35:25 +0200 Subject: [PATCH 11/26] Add DirectoryExamples for get user and get users. --- .../java/org/example/DirectoryExample.java | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/examples/directory-example/src/main/java/org/example/DirectoryExample.java b/examples/directory-example/src/main/java/org/example/DirectoryExample.java index 3f66f4f..4f69fa8 100644 --- a/examples/directory-example/src/main/java/org/example/DirectoryExample.java +++ b/examples/directory-example/src/main/java/org/example/DirectoryExample.java @@ -1,7 +1,40 @@ package org.example; +import com.aserto.ChannelBuilder; +import com.aserto.directory.DirectoryClient; +import com.aserto.directory.reader.v3.GetObjectResponse; +import com.aserto.directory.reader.v3.GetObjectsResponse; +import io.grpc.ManagedChannel; + +import javax.net.ssl.SSLException; + public class DirectoryExample { - public static void main(String[] args) { - System.out.println("Hello world!"); + public static void main(String[] args) throws SSLException { + // create a channel that has the connection details + ManagedChannel channel = new ChannelBuilder() + .withHost("localhost") + .withPort(9292) + .withInsecure(true) + .build(); + + // create a directory client that wil be used to interact with the directory + DirectoryClient directoryClient = new DirectoryClient(channel); + + getUserExample(directoryClient); + getUsersExample(directoryClient); + } + + public static void getUserExample(DirectoryClient directoryClient) { + System.out.println("------ Get user example ------"); + GetObjectResponse getObjectResponse = directoryClient.getObject("user", "morty@the-citadel.com", false); + System.out.println(getObjectResponse); + } + + public static void getUsersExample(DirectoryClient directoryClient) { + System.out.println("------ Get users example ------"); + GetObjectsResponse getObjectsResponse = directoryClient.getObjects("user", 100, ""); + System.out.println(getObjectsResponse); } + + } \ No newline at end of file From a73897bf2e903297da72e8e7b75fdbf50c5f9a69 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Mon, 20 Nov 2023 16:25:15 +0200 Subject: [PATCH 12/26] Return GetObjectManyResponse from getObjectManyRequest --- src/main/java/com/aserto/directory/DirectoryClient.java | 6 +++--- .../java/com/aserto/directory/DirectoryClientReader.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/aserto/directory/DirectoryClient.java b/src/main/java/com/aserto/directory/DirectoryClient.java index 0190df6..84baa9b 100644 --- a/src/main/java/com/aserto/directory/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/DirectoryClient.java @@ -89,10 +89,10 @@ public GetObjectsResponse getObjects(String type, int pageSize, String pageToken } @Override - public GetObjectManyRequest getObjectManyRequest(List objectIdentifiers) { - return GetObjectManyRequest.newBuilder() + public GetObjectManyResponse getObjectManyRequest(List objectIdentifiers) { + return readerClient.getObjectMany(GetObjectManyRequest.newBuilder() .addAllParam(new ObjectIdentifierList(objectIdentifiers)) - .build(); + .build()); } private PaginationRequest buildPaginationRequest(int pageSize, String pageToken) { diff --git a/src/main/java/com/aserto/directory/DirectoryClientReader.java b/src/main/java/com/aserto/directory/DirectoryClientReader.java index e20d605..9023c5d 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientReader.java +++ b/src/main/java/com/aserto/directory/DirectoryClientReader.java @@ -10,7 +10,7 @@ public interface DirectoryClientReader { public GetObjectResponse getObject(String type, String id, boolean withRelations); public GetObjectsResponse getObjects(String type); public GetObjectsResponse getObjects(String type, int pageSize, String pageToken); - public GetObjectManyRequest getObjectManyRequest(List objectIdentifiers); + public GetObjectManyResponse getObjectManyRequest(List objectIdentifiers); public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation); public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, From 827d6c843b07a802e8793a82ab13a9867b3fca3c Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Mon, 20 Nov 2023 17:32:44 +0200 Subject: [PATCH 13/26] Use a builder pattern for getRelations as all the arguments are optional. --- .../com/aserto/directory/DirectoryClient.java | 19 ++----------------- .../directory/DirectoryClientReader.java | 7 ++----- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/aserto/directory/DirectoryClient.java b/src/main/java/com/aserto/directory/DirectoryClient.java index 84baa9b..da457bf 100644 --- a/src/main/java/com/aserto/directory/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/DirectoryClient.java @@ -102,7 +102,6 @@ private PaginationRequest buildPaginationRequest(int pageSize, String pageToken) .build(); } - @Override public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation) { return getRelation(objectType, objectId, relationName, subjectType, subjectId, subjectRelation, false); @@ -121,22 +120,8 @@ public GetRelationResponse getRelation(String objectType, String objectId, Strin } @Override - public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects) { - return getRelations(objectType, objectId, relationName, subjectType, subjectId, subjectRelation, withObjects, 100, ""); - } - - @Override - public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects, int pageSize, String pageToken) { - return readerClient.getRelations(GetRelationsRequest.newBuilder() - .setObjectType(objectType) - .setObjectId(objectId) - .setRelation(relationName) - .setSubjectType(subjectType) - .setSubjectId(subjectId) - .setSubjectRelation(subjectRelation) - .setWithObjects(withObjects) - .setPage(buildPaginationRequest(pageSize, pageToken)) - .build()); + public GetRelationsResponse getRelations(GetRelationsRequest relationsRequest) { + return readerClient.getRelations(relationsRequest); } @Override diff --git a/src/main/java/com/aserto/directory/DirectoryClientReader.java b/src/main/java/com/aserto/directory/DirectoryClientReader.java index 9023c5d..88f7f12 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientReader.java +++ b/src/main/java/com/aserto/directory/DirectoryClientReader.java @@ -15,11 +15,8 @@ public GetRelationResponse getRelation(String objectType, String objectId, Strin String subjectId, String subjectRelation); public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects); - public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, - String subjectType, String subjectId, String subjectRelation, boolean withObjects); - public GetRelationsResponse getRelations(String objectType, String objectId, String relationName, - String subjectType, String subjectId, String subjectRelation, - boolean withObjects, int pageSize, String pageToken); + public GetRelationsResponse getRelations(GetRelationsRequest relationsRequest); + public CheckPermissionResponse checkPermission(String objectType, String objectId, String subjectType, String subjectId, String permissionName); public CheckPermissionResponse checkPermission(String objectType, String objectId, From de604546d111186bf3bc7df59357dc8df580c540 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Wed, 22 Nov 2023 15:21:02 +0200 Subject: [PATCH 14/26] Add automation to start Topaz for integration tests. Add more integration test for the directory api. Removed junit-platform-runner as it was interfering with the Junit5 tests. --- .github/workflows/ci.yaml | 10 +- .../java/org/example/DirectoryExample.java | 20 ++- pom.xml | 10 +- .../com/aserto/directory/DirectoryClient.java | 5 + .../directory/DirectoryClientReader.java | 2 + src/test/java/AuthzClientIntegrationTest.java | 6 +- src/test/java/AuthzClientTest.java | 21 +-- src/test/java/DirectoryClientBuilderTest.java | 18 +- src/test/java/DirectoryClientTest.java | 142 ++++++++++++++++ src/test/java/IntegrationTestsExtenion.java | 33 ++++ src/test/java/Topaz.java | 159 ++++++++++++++++++ 11 files changed, 393 insertions(+), 33 deletions(-) create mode 100644 src/test/java/DirectoryClientTest.java create mode 100644 src/test/java/IntegrationTestsExtenion.java create mode 100644 src/test/java/Topaz.java diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 387c966..eba3929 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -31,8 +31,14 @@ jobs: java-version: 8 distribution: temurin - - name: Run tests - run: mvn clean test + - name: Set up Homebrew + uses: Homebrew/actions/setup-homebrew@master + + - name: Install topaz + run: brew tap aserto-dev/tap && brew install aserto-dev/tap/topaz && topaz install + + - name: Run all tests + run: mvn clean test -Pintegration release: runs-on: ubuntu-latest needs: build diff --git a/examples/directory-example/src/main/java/org/example/DirectoryExample.java b/examples/directory-example/src/main/java/org/example/DirectoryExample.java index 4f69fa8..d84faf8 100644 --- a/examples/directory-example/src/main/java/org/example/DirectoryExample.java +++ b/examples/directory-example/src/main/java/org/example/DirectoryExample.java @@ -2,11 +2,14 @@ import com.aserto.ChannelBuilder; import com.aserto.directory.DirectoryClient; +import com.aserto.directory.common.v3.ObjectIdentifier; +import com.aserto.directory.reader.v3.GetObjectManyResponse; import com.aserto.directory.reader.v3.GetObjectResponse; import com.aserto.directory.reader.v3.GetObjectsResponse; import io.grpc.ManagedChannel; import javax.net.ssl.SSLException; +import java.util.List; public class DirectoryExample { public static void main(String[] args) throws SSLException { @@ -22,6 +25,7 @@ public static void main(String[] args) throws SSLException { getUserExample(directoryClient); getUsersExample(directoryClient); + getObjectManyRequest(directoryClient); } public static void getUserExample(DirectoryClient directoryClient) { @@ -36,5 +40,19 @@ public static void getUsersExample(DirectoryClient directoryClient) { System.out.println(getObjectsResponse); } - + public static void getObjectManyRequest(DirectoryClient directoryClient) { + System.out.println("------ Get object many example ------"); + List objects = List.of( + ObjectIdentifier.newBuilder() + .setObjectType("user") + .setObjectId("rick@the-citadel.com") + .build(), + ObjectIdentifier.newBuilder() + .setObjectType("user") + .setObjectId("morty@the-citadel.com") + .build()); + + GetObjectManyResponse getObjectManyRequest = directoryClient.getObjectManyRequest(objects); + System.out.println(getObjectManyRequest); + } } \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8724f79..b7df20e 100644 --- a/pom.xml +++ b/pom.xml @@ -61,13 +61,7 @@ org.junit.jupiter junit-jupiter-engine - 5.10.0 - test - - - org.junit.platform - junit-platform-runner - 1.10.0 + 5.10.1 test @@ -186,7 +180,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.1.2 + 3.2.2 ${exclude-tests} diff --git a/src/main/java/com/aserto/directory/DirectoryClient.java b/src/main/java/com/aserto/directory/DirectoryClient.java index da457bf..2b1168a 100644 --- a/src/main/java/com/aserto/directory/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/DirectoryClient.java @@ -102,6 +102,11 @@ private PaginationRequest buildPaginationRequest(int pageSize, String pageToken) .build(); } + @Override + public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId) { + return getRelation(objectType, objectId, relationName, subjectType, subjectId, "", false); + } + @Override public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation) { return getRelation(objectType, objectId, relationName, subjectType, subjectId, subjectRelation, false); diff --git a/src/main/java/com/aserto/directory/DirectoryClientReader.java b/src/main/java/com/aserto/directory/DirectoryClientReader.java index 88f7f12..75e414a 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientReader.java +++ b/src/main/java/com/aserto/directory/DirectoryClientReader.java @@ -11,6 +11,8 @@ public interface DirectoryClientReader { public GetObjectsResponse getObjects(String type); public GetObjectsResponse getObjects(String type, int pageSize, String pageToken); public GetObjectManyResponse getObjectManyRequest(List objectIdentifiers); + public GetRelationResponse getRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId); public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation); public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, diff --git a/src/test/java/AuthzClientIntegrationTest.java b/src/test/java/AuthzClientIntegrationTest.java index 40de99f..49f4261 100644 --- a/src/test/java/AuthzClientIntegrationTest.java +++ b/src/test/java/AuthzClientIntegrationTest.java @@ -5,6 +5,7 @@ import io.grpc.StatusRuntimeException; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import javax.net.ssl.SSLException; import java.io.IOException; @@ -14,6 +15,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; @Tag("IntegrationTest") +@ExtendWith({IntegrationTestsExtenion.class}) class AuthzClientIntegrationTest { @Test @Tag("IntegrationTest") @@ -33,7 +35,7 @@ void testBuildAuthzClient() throws IOException { authzClient.close(); // Assert - assertEquals(6, policies.size()); + assertEquals(5, policies.size()); } @Test @@ -53,7 +55,7 @@ void testInsecureConnectionToInsecureClient() throws SSLException { authzClient.close(); // Assert - assertEquals(6, policies.size()); + assertEquals(5, policies.size()); } @Test diff --git a/src/test/java/AuthzClientTest.java b/src/test/java/AuthzClientTest.java index f61c571..4a43c7a 100644 --- a/src/test/java/AuthzClientTest.java +++ b/src/test/java/AuthzClientTest.java @@ -12,10 +12,7 @@ import io.grpc.inprocess.InProcessServerBuilder; import io.grpc.stub.StreamObserver; import io.grpc.testing.GrpcCleanupRule; -import org.junit.Rule; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; import javax.net.ssl.SSLException; import java.io.IOException; @@ -27,12 +24,10 @@ class AuthzClientTest { - - @Rule - public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule(); + public static final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule(); // Will be used to mock the grpc server - private final AuthorizerGrpc.AuthorizerImplBase serviceImpl = + private static final AuthorizerGrpc.AuthorizerImplBase serviceImpl = mock(AuthorizerGrpc.AuthorizerImplBase.class, delegatesTo( new AuthorizerGrpc.AuthorizerImplBase() { // Implement necessary behaviour for tests by overriding the grpc called methods @@ -114,10 +109,10 @@ public void getPolicy(GetPolicyRequest request, StreamObserver objects = List.of( + ObjectIdentifier.newBuilder() + .setObjectType("user") + .setObjectId("rick@the-citadel.com") + .build(), + ObjectIdentifier.newBuilder() + .setObjectType("user") + .setObjectId("morty@the-citadel.com") + .build()); + + // Act + GetObjectManyResponse getObjectManyResponse = directoryClient.getObjectManyRequest(objects); + + // Assert + Set actualUsers = getObjectManyResponse.getResultsList().stream().map(Object::getId).collect(Collectors.toSet()); + Set expectedUsers = objects.stream().map(ObjectIdentifier::getObjectId).collect(Collectors.toSet()); + + assertEquals(actualUsers, expectedUsers); + } + + @Test + @Tag("IntegrationTest") + void testGetRelation() { + // Arrange + GetRelationResponse getRelationResponse = directoryClient.getRelation( + "group", + "editor", + "member", + "user", + "morty@the-citadel.com"); + + // Act + Relation relation = getRelationResponse.getResult(); + + // Assert + assertEquals("group", relation.getObjectType()); + assertEquals("editor", relation.getObjectId()); + assertEquals("member", relation.getRelation()); + assertEquals("user", relation.getSubjectType()); + assertEquals("morty@the-citadel.com", relation.getSubjectId()); + } + + @Test + @Tag("IntegrationTest") + void testGetRelations() { + // Arrange + GetRelationsRequest getRelationsRequest = GetRelationsRequest.newBuilder().setObjectType("identity").build(); + + // Act + GetRelationsResponse getRelationsResponse = directoryClient.getRelations(getRelationsRequest); + + // Assert + assertEquals(10, getRelationsResponse.getResultsList().size()); + } +} diff --git a/src/test/java/IntegrationTestsExtenion.java b/src/test/java/IntegrationTestsExtenion.java new file mode 100644 index 0000000..d469793 --- /dev/null +++ b/src/test/java/IntegrationTestsExtenion.java @@ -0,0 +1,33 @@ +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +import java.io.IOException; +import java.net.URISyntaxException; + +import static org.junit.jupiter.api.extension.ExtensionContext.Namespace.GLOBAL; + +public class IntegrationTestsExtenion implements BeforeAllCallback, ExtensionContext.Store.CloseableResource { + + private static boolean started = false; + private static Topaz topaz; + + @Override + public void beforeAll(ExtensionContext context) throws IOException, InterruptedException, URISyntaxException { + if (!started) { + started = true; +// Your "before all tests" startup logic goes here +// https://stackoverflow.com/questions/43282798/in-junit-5-how-to-run-code-before-all-tests + topaz = new Topaz(); + topaz.run(); + +// The following line registers a callback hook when the root test context is shut down + context.getRoot().getStore(GLOBAL).put("test close hook", this); + } + + } + + @Override + public void close() throws IOException, InterruptedException { + topaz.stop(); + } +} \ No newline at end of file diff --git a/src/test/java/Topaz.java b/src/test/java/Topaz.java new file mode 100644 index 0000000..aae1a6e --- /dev/null +++ b/src/test/java/Topaz.java @@ -0,0 +1,159 @@ +import com.aserto.ChannelBuilder; +import com.aserto.directory.DirectoryClient; +import io.grpc.ManagedChannel; + +import javax.net.ssl.SSLException; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Duration; +import java.util.concurrent.*; +import java.net.URI; + +public class Topaz { + private String HOME_DIR = System.getProperty("user.home"); + private String DB_DIR = HOME_DIR + "/.config/topaz/db"; + private String TOPAZ_CFG_DIR = HOME_DIR + "/.config/topaz/cfg"; + private DirectoryClient directoryClient; + + public Topaz() throws SSLException { + ManagedChannel channel = new ChannelBuilder() + .withHost("localhost") + .withPort(9292) + .withInsecure(true) + .build(); + directoryClient = new DirectoryClient(channel); + + } + + public void run() throws IOException, InterruptedException, URISyntaxException { + stop(); + backupDb(); + backupCfg(); + configure(); + start(); + loadData(); + } + + public void stop() throws IOException, InterruptedException { + Process process = new ProcessBuilder("topaz","stop").start(); + process.waitFor(); + restoreDb(); + restoreCfg(); + deleteDirectory(new File("temp")); + } + + private void loadData() throws IOException, URISyntaxException, InterruptedException { + downloadFile("https://raw.githubusercontent.com/aserto-dev/topaz/main/assets/citadel/citadel_objects.json", "temp/citadel_objects.json"); + downloadFile("https://raw.githubusercontent.com/aserto-dev/topaz/main/assets/citadel/citadel_relations.json", "temp/citadel_relations.json"); + + ProcessBuilder pb = new ProcessBuilder("topaz","import", "-i", "-d", "temp/"); + pb.inheritIO(); + Process process = pb.start(); + process.waitFor(); + } + + private void removeTempFile(String... files) { + for (String file: files) { + File tempFile = new File(file); + if(tempFile.exists()) { + tempFile.delete(); + } + } + } + + private void deleteDirectory(File directoryToBeDeleted) { + File[] allContents = directoryToBeDeleted.listFiles(); + if (allContents != null) { + for (File file : allContents) { + deleteDirectory(file); + } + } + directoryToBeDeleted.delete(); + } + + private void downloadFile(String url, String filePath) throws IOException, URISyntaxException { + Files.createDirectories(Paths.get(filePath).getParent()); + + BufferedInputStream in = new BufferedInputStream(new URI(url).toURL().openStream()); + FileOutputStream fileOutputStream = new FileOutputStream(filePath); + byte dataBuffer[] = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { + fileOutputStream.write(dataBuffer, 0, bytesRead); + } + } + + private void start() throws IOException, InterruptedException { + ProcessBuilder pb = new ProcessBuilder("topaz","start"); + pb.inheritIO(); + Process process = pb.start(); + process.waitFor(); + process.waitFor(); + + final Duration timeout = Duration.ofSeconds(60); + ExecutorService executor = Executors.newSingleThreadExecutor(); + + final Future handler = executor.submit(new Callable() { + @Override + public Integer call() throws Exception { + while (true) { + try { + directoryClient.getObjects("user"); + } catch (Exception e) { + Thread.sleep(2000); + continue; + } + + return directoryClient.getObjects("user").getResultsList().size(); + } + } + }); + + try { + handler.get(timeout.toMillis(), TimeUnit.MILLISECONDS); + } catch (TimeoutException | InterruptedException | ExecutionException e) { + handler.cancel(true); + } + + } + + private void configure() throws IOException, InterruptedException { + ProcessBuilder pb = new ProcessBuilder("topaz", "configure", "-r", "ghcr.io/aserto-policies/policy-todo:2.1.0", "-n", "todo", "-d", "-s"); + pb.inheritIO(); + Process process = pb.start(); + process.waitFor(); + } + + private void backupDb() { + File directoryDb = new File(DB_DIR + "/directory.db" ); + if(directoryDb.exists()) { + directoryDb.renameTo(new File(DB_DIR + "/directory.db.bak" )); + } + } + + private void restoreDb() { + File directoryDb = new File(DB_DIR + "/directory.db.bak" ); + if(directoryDb.exists()) { + directoryDb.renameTo(new File(DB_DIR + "/directory.db" )); + } + } + + private void backupCfg() { + File directoryDb = new File(TOPAZ_CFG_DIR + "/config.yaml" ); + if(directoryDb.exists()) { + directoryDb.renameTo(new File(TOPAZ_CFG_DIR + "/config.yaml.bak" )); + } + } + + private void restoreCfg() { + File directoryDb = new File(TOPAZ_CFG_DIR + "/config.yaml.bak" ); + if(directoryDb.exists()) { + directoryDb.renameTo(new File(TOPAZ_CFG_DIR + "/config.yaml" )); + } + } +} From b13ceb749deecddc97960b9a1ebdf7b975a4c52e Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Wed, 22 Nov 2023 15:23:33 +0200 Subject: [PATCH 15/26] Bump to java 17 --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index eba3929..d10a714 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -28,7 +28,7 @@ jobs: - name: Set up Java for publishing to Maven Central Repository uses: actions/setup-java@v3 with: - java-version: 8 + java-version: 17 distribution: temurin - name: Set up Homebrew From e7b3058f77688c25d399621a4773cfd9f67576a7 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Wed, 22 Nov 2023 15:30:11 +0200 Subject: [PATCH 16/26] Add the v3 namespace for directory. --- .../java/com/aserto/directory/{ => v3}/DirectoryClient.java | 2 +- .../aserto/directory/{ => v3}/DirectoryClientBuilder.java | 2 +- .../aserto/directory/{ => v3}/DirectoryClientExporter.java | 2 +- .../aserto/directory/{ => v3}/DirectoryClientImporter.java | 2 +- .../com/aserto/directory/{ => v3}/DirectoryClientModel.java | 2 +- .../com/aserto/directory/{ => v3}/DirectoryClientReader.java | 2 +- .../com/aserto/directory/{ => v3}/DirectoryClientWriter.java | 2 +- .../com/aserto/directory/{ => v3}/ObjectIdentifierList.java | 2 +- src/test/java/AuthzClientIntegrationTest.java | 1 + src/test/java/DirectoryClientBuilderTest.java | 2 +- src/test/java/DirectoryClientTest.java | 5 +++-- src/test/java/{ => utils}/IntegrationTestsExtenion.java | 2 ++ src/test/java/{ => utils}/Topaz.java | 4 +++- 13 files changed, 18 insertions(+), 12 deletions(-) rename src/main/java/com/aserto/directory/{ => v3}/DirectoryClient.java (99%) rename src/main/java/com/aserto/directory/{ => v3}/DirectoryClientBuilder.java (99%) rename src/main/java/com/aserto/directory/{ => v3}/DirectoryClientExporter.java (88%) rename src/main/java/com/aserto/directory/{ => v3}/DirectoryClientImporter.java (86%) rename src/main/java/com/aserto/directory/{ => v3}/DirectoryClientModel.java (91%) rename src/main/java/com/aserto/directory/{ => v3}/DirectoryClientReader.java (98%) rename src/main/java/com/aserto/directory/{ => v3}/DirectoryClientWriter.java (97%) rename src/main/java/com/aserto/directory/{ => v3}/ObjectIdentifierList.java (92%) rename src/test/java/{ => utils}/IntegrationTestsExtenion.java (98%) rename src/test/java/{ => utils}/Topaz.java (98%) diff --git a/src/main/java/com/aserto/directory/DirectoryClient.java b/src/main/java/com/aserto/directory/v3/DirectoryClient.java similarity index 99% rename from src/main/java/com/aserto/directory/DirectoryClient.java rename to src/main/java/com/aserto/directory/v3/DirectoryClient.java index 2b1168a..f87147f 100644 --- a/src/main/java/com/aserto/directory/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClient.java @@ -1,4 +1,4 @@ -package com.aserto.directory; +package com.aserto.directory.v3; import com.aserto.ChannelBuilder; import com.aserto.utils.MessageChunker; diff --git a/src/main/java/com/aserto/directory/DirectoryClientBuilder.java b/src/main/java/com/aserto/directory/v3/DirectoryClientBuilder.java similarity index 99% rename from src/main/java/com/aserto/directory/DirectoryClientBuilder.java rename to src/main/java/com/aserto/directory/v3/DirectoryClientBuilder.java index 41820fe..a136d18 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientBuilder.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientBuilder.java @@ -1,4 +1,4 @@ -package com.aserto.directory; +package com.aserto.directory.v3; import com.aserto.directory.exporter.v3.ExporterGrpc; import com.aserto.directory.importer.v3.ImporterGrpc; diff --git a/src/main/java/com/aserto/directory/DirectoryClientExporter.java b/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java similarity index 88% rename from src/main/java/com/aserto/directory/DirectoryClientExporter.java rename to src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java index 1759f22..566e398 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientExporter.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java @@ -1,4 +1,4 @@ -package com.aserto.directory; +package com.aserto.directory.v3; import com.aserto.directory.exporter.v3.ExportResponse; import com.google.protobuf.Timestamp; diff --git a/src/main/java/com/aserto/directory/DirectoryClientImporter.java b/src/main/java/com/aserto/directory/v3/DirectoryClientImporter.java similarity index 86% rename from src/main/java/com/aserto/directory/DirectoryClientImporter.java rename to src/main/java/com/aserto/directory/v3/DirectoryClientImporter.java index 54af1e3..aea6276 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientImporter.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientImporter.java @@ -1,4 +1,4 @@ -package com.aserto.directory; +package com.aserto.directory.v3; import com.aserto.model.ImportElement; import java.util.stream.Stream; diff --git a/src/main/java/com/aserto/directory/DirectoryClientModel.java b/src/main/java/com/aserto/directory/v3/DirectoryClientModel.java similarity index 91% rename from src/main/java/com/aserto/directory/DirectoryClientModel.java rename to src/main/java/com/aserto/directory/v3/DirectoryClientModel.java index 96a9725..b3581fb 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientModel.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientModel.java @@ -1,4 +1,4 @@ -package com.aserto.directory; +package com.aserto.directory.v3; import com.aserto.directory.model.v3.DeleteManifestResponse; import com.aserto.directory.model.v3.GetManifestResponse; diff --git a/src/main/java/com/aserto/directory/DirectoryClientReader.java b/src/main/java/com/aserto/directory/v3/DirectoryClientReader.java similarity index 98% rename from src/main/java/com/aserto/directory/DirectoryClientReader.java rename to src/main/java/com/aserto/directory/v3/DirectoryClientReader.java index 75e414a..a258dfd 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientReader.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientReader.java @@ -1,4 +1,4 @@ -package com.aserto.directory; +package com.aserto.directory.v3; import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.reader.v3.*; diff --git a/src/main/java/com/aserto/directory/DirectoryClientWriter.java b/src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java similarity index 97% rename from src/main/java/com/aserto/directory/DirectoryClientWriter.java rename to src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java index 51151b0..99e5759 100644 --- a/src/main/java/com/aserto/directory/DirectoryClientWriter.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java @@ -1,4 +1,4 @@ -package com.aserto.directory; +package com.aserto.directory.v3; import com.aserto.directory.writer.v3.DeleteObjectResponse; import com.aserto.directory.writer.v3.DeleteRelationResponse; diff --git a/src/main/java/com/aserto/directory/ObjectIdentifierList.java b/src/main/java/com/aserto/directory/v3/ObjectIdentifierList.java similarity index 92% rename from src/main/java/com/aserto/directory/ObjectIdentifierList.java rename to src/main/java/com/aserto/directory/v3/ObjectIdentifierList.java index bd8dc26..886b7d6 100644 --- a/src/main/java/com/aserto/directory/ObjectIdentifierList.java +++ b/src/main/java/com/aserto/directory/v3/ObjectIdentifierList.java @@ -1,4 +1,4 @@ -package com.aserto.directory; +package com.aserto.directory.v3; import com.aserto.directory.common.v3.ObjectIdentifier; diff --git a/src/test/java/AuthzClientIntegrationTest.java b/src/test/java/AuthzClientIntegrationTest.java index 49f4261..e66c549 100644 --- a/src/test/java/AuthzClientIntegrationTest.java +++ b/src/test/java/AuthzClientIntegrationTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import utils.IntegrationTestsExtenion; import javax.net.ssl.SSLException; import java.io.IOException; diff --git a/src/test/java/DirectoryClientBuilderTest.java b/src/test/java/DirectoryClientBuilderTest.java index eb09670..143ff33 100644 --- a/src/test/java/DirectoryClientBuilderTest.java +++ b/src/test/java/DirectoryClientBuilderTest.java @@ -1,4 +1,4 @@ -import com.aserto.directory.DirectoryClientBuilder; +import com.aserto.directory.v3.DirectoryClientBuilder; import io.grpc.ManagedChannel; import io.grpc.inprocess.InProcessChannelBuilder; import io.grpc.inprocess.InProcessServerBuilder; diff --git a/src/test/java/DirectoryClientTest.java b/src/test/java/DirectoryClientTest.java index 8bb34e4..b3e7f5a 100644 --- a/src/test/java/DirectoryClientTest.java +++ b/src/test/java/DirectoryClientTest.java @@ -1,5 +1,5 @@ import com.aserto.ChannelBuilder; -import com.aserto.directory.DirectoryClient; +import com.aserto.directory.v3.DirectoryClient; import com.aserto.directory.common.v3.Object; import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.common.v3.Relation; @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import utils.IntegrationTestsExtenion; import javax.net.ssl.SSLException; @@ -21,7 +22,7 @@ @Tag("IntegrationTest") @ExtendWith({IntegrationTestsExtenion.class}) -public class DirectoryClientTest { +class DirectoryClientTest { private static DirectoryClient directoryClient; @BeforeAll diff --git a/src/test/java/IntegrationTestsExtenion.java b/src/test/java/utils/IntegrationTestsExtenion.java similarity index 98% rename from src/test/java/IntegrationTestsExtenion.java rename to src/test/java/utils/IntegrationTestsExtenion.java index d469793..1ff0cfa 100644 --- a/src/test/java/IntegrationTestsExtenion.java +++ b/src/test/java/utils/IntegrationTestsExtenion.java @@ -1,3 +1,5 @@ +package utils; + import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.ExtensionContext; diff --git a/src/test/java/Topaz.java b/src/test/java/utils/Topaz.java similarity index 98% rename from src/test/java/Topaz.java rename to src/test/java/utils/Topaz.java index aae1a6e..dd9d1ba 100644 --- a/src/test/java/Topaz.java +++ b/src/test/java/utils/Topaz.java @@ -1,5 +1,7 @@ +package utils; + import com.aserto.ChannelBuilder; -import com.aserto.directory.DirectoryClient; +import com.aserto.directory.v3.DirectoryClient; import io.grpc.ManagedChannel; import javax.net.ssl.SSLException; From f44cd5603ade47d25776acd303bc54f37d2215ca Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Wed, 22 Nov 2023 15:50:35 +0200 Subject: [PATCH 17/26] FIx the exporter interface and clean commented out code. --- .../aserto/directory/v3/DirectoryClient.java | 115 +----------------- .../directory/v3/DirectoryClientBuilder.java | 18 --- .../directory/v3/DirectoryClientExporter.java | 3 +- 3 files changed, 5 insertions(+), 131 deletions(-) diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClient.java b/src/main/java/com/aserto/directory/v3/DirectoryClient.java index f87147f..a148116 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClient.java @@ -1,6 +1,5 @@ package com.aserto.directory.v3; -import com.aserto.ChannelBuilder; import com.aserto.utils.MessageChunker; import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.common.v3.PaginationRequest; @@ -27,7 +26,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import javax.net.ssl.SSLException; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.time.Instant; @@ -40,7 +38,8 @@ public class DirectoryClient implements DirectoryClientReader, DirectoryClientWriter, DirectoryClientModel, - DirectoryClientImporter { + DirectoryClientImporter, + DirectoryClientExporter { static final int MAX_CHUNK_SIZE = 65536; Logger logger = LogManager.getLogger(DirectoryClient.class); private ReaderGrpc.ReaderBlockingStub readerClient; @@ -60,8 +59,6 @@ public DirectoryClient(ManagedChannel channelBuilder) { modelClientAsync = dirClientBuilder.getModelClientAsync(); } - - @Override public GetObjectResponse getObject(String type, String id) { return getObject(type, id, false); @@ -286,7 +283,6 @@ public GetManifestResponse getManifest() { outputStream.write(manifestResponse.getBody().getData().toByteArray()); } catch (IOException e) { logger.error("Could not write to stream the fallowing message: {}", manifestResponse.getBody().getData().toByteArray()); - throw new RuntimeException(e); } } }); @@ -382,116 +378,11 @@ public void onCompleted() { } } + @Override public Iterator exportData(Option options, Timestamp startFrom) { return exporterClient.export(ExportRequest.newBuilder() .setOptions(options.getNumber()) .setStartFrom(startFrom) .build()); } - - - public static void main(String[] args) throws SSLException, InterruptedException { - // create a channel that has the connection details - ManagedChannel channel = new ChannelBuilder() - .withHost("localhost") - .withPort(9292) - .withInsecure(true) - .build(); - - DirectoryClient directoryClient = new DirectoryClient(channel); - -// GetObjectResponse getObjectResponse = directoryClient.getObject("user", "morty@the-citadel.com", false); -// GetManifestResponse getManifestResponse = directoryClient.getManifest(); -// -// System.out.println(getObjectResponse.toString()); -// System.out.println(getManifestResponse.getBody().getData().toStringUtf8()); - -// --------------------------- -// List objects = List.of( -// ObjectIdentifier.newBuilder() -// .setObjectType("user") -// .setObjectId("rick@the-citadel.com") -// .build(), -// ObjectIdentifier.newBuilder() -// .setObjectType("user") -// .setObjectId("morty@the-citadel.com") -// .build()); -// -// GetObjectManyRequest getObjectManyRequest = directoryClient.getObjectManyRequest(objects); -// System.out.println(getObjectManyRequest); -// -------------------------------------- - -// GetGraphResponse getGraphResponse = directoryClient.getGraph("user", "rick@the-citadel.com", "user", "rick@the-citadel.com","", "", "", ""); -// System.out.println(getGraphResponse); -// --------------------------------- - - -// String manifest = "# yaml-language-server: $schema=https://www.topaz.sh/schema/manifest.json\n" + -// "---\n" + -// "### model ###\n" + -// "model:\n" + -// " version: 3\n" + -// "\n" + -// "### object type definitions ###\n" + -// "types:\n" + -// " ### display_name: User ###\n" + -// " user:\n" + -// " relations:\n" + -// " ### display_name: user#manager ###\n" + -// " manager: user\n" + -// "\n" + -// " ### display_name: Identity ###\n" + -// " identity:\n" + -// " relations:\n" + -// " ### display_name: identity#identifier ###\n" + -// " identifier: user\n" + -// "\n" + -// " ### display_name: Group ###\n" + -// " group:\n" + -// " relations:\n" + -// " ### display_name: group#member ###\n" + -// " member: user"; -// -// directoryClient.setManifest(manifest); -// -// -// System.out.println(directoryClient.getManifest().getBody().getData().toStringUtf8()); - -// -------------------------------------- - - -// List list = new ArrayList<>(); -// Object user = Object.newBuilder() -// .setType("user") -// .setId("test@aserto.com").build(); -// Relation managerRelation = Relation.newBuilder() -// .setObjectType("user") -// .setObjectId("test@aserto.com") -// .setRelation("manager") -// .setSubjectType("user") -// .setSubjectId("morty@the-citadel.com") -// .build(); -// -// list.add(new ImportElement(user)); -// list.add(new ImportElement(managerRelation)); -// -// directoryClient.importData(list.stream()); -// -// -// directoryClient.getObjects("user", 10, ""); -// directoryClient.getObject("user", "test@aserto.com", true); - -// --------------------------------------- -// directoryClient.setObject("user", "test", "test", Struct.newBuilder().build(), ""); - - -// ----------------------------------- - Iterator exportedData = directoryClient.exportData( Option.OPTION_DATA, Timestamp.newBuilder().setSeconds(0).setNanos(0).build()); - exportedData.forEachRemaining(System.out::println); -// ----------------------------------- - - } - - - } diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClientBuilder.java b/src/main/java/com/aserto/directory/v3/DirectoryClientBuilder.java index a136d18..3cc6308 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClientBuilder.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientBuilder.java @@ -88,24 +88,6 @@ public ModelGrpc.ModelStub getModelClientAsync() { return modelClientAsync; } - class Result { - private T[] results; - private String nextPageToken; - - public Result(T[] results, String nextPageToken) { - this.results = results; - this.nextPageToken = nextPageToken; - } - - public T[] getResults() { - return results; - } - - public String getNextPageToken() { - return nextPageToken; - } - } - public void close() { if (channel != null) { channel.shutdown(); diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java b/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java index 566e398..9633b86 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java @@ -1,10 +1,11 @@ package com.aserto.directory.v3; import com.aserto.directory.exporter.v3.ExportResponse; +import com.aserto.directory.exporter.v3.Option; import com.google.protobuf.Timestamp; import java.util.Iterator; public interface DirectoryClientExporter { - Iterator exportData(int options, Timestamp startFrom); + Iterator exportData(Option options, Timestamp startFrom); } From c29a2b0789f2e9e361623292188c9c76c7683552 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Wed, 22 Nov 2023 18:41:06 +0200 Subject: [PATCH 18/26] Use a builder pattern for getGraph api. --- .../com/aserto/directory/v3/DirectoryClient.java | 15 +++------------ .../directory/v3/DirectoryClientReader.java | 3 +-- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClient.java b/src/main/java/com/aserto/directory/v3/DirectoryClient.java index a148116..1d9e285 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClient.java @@ -177,19 +177,10 @@ public CheckResponse check(String objectType, String objectId, String relationNa .build()); } + @Override - public GetGraphResponse getGraph(String anchorType, String anchorId, String objectType, String objectId, - String relation, String subjectType, String subjectId, String subjectRelation) { - return readerClient.getGraph(GetGraphRequest.newBuilder() - .setAnchorType(anchorType) - .setAnchorId(anchorId) - .setObjectType(objectType) - .setObjectId(objectId) - .setRelation(relation) - .setSubjectType(subjectType) - .setSubjectId(subjectId) - .setSubjectRelation(subjectRelation) - .build()); + public GetGraphResponse getGraph(GetGraphRequest getGraphRequest) { + return readerClient.getGraph(getGraphRequest); } @Override diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClientReader.java b/src/main/java/com/aserto/directory/v3/DirectoryClientReader.java index a258dfd..bd3a20b 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClientReader.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientReader.java @@ -29,6 +29,5 @@ public CheckRelationResponse checkRelation(String objectType, String objectId, S public CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId); public CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId, boolean trace); - public GetGraphResponse getGraph(String anchorType, String anchorId, String objectType, String objectId, - String relation, String subjectType, String subjectId, String subjectRelation); + public GetGraphResponse getGraph(GetGraphRequest getGraphRequest); } From 2602cc9ca30c6cb857360d1f7d574f2759c38411 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Wed, 22 Nov 2023 18:42:47 +0200 Subject: [PATCH 19/26] Add more unit tests for the directory reader api. Use assertj to improve assertions in tests. --- pom.xml | 6 ++ src/test/java/DirectoryClientTest.java | 101 ++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index b7df20e..7b755d5 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,12 @@ 5.10.1 test + + org.assertj + assertj-core + 3.24.2 + test + io.grpc grpc-testing diff --git a/src/test/java/DirectoryClientTest.java b/src/test/java/DirectoryClientTest.java index b3e7f5a..e2c4f85 100644 --- a/src/test/java/DirectoryClientTest.java +++ b/src/test/java/DirectoryClientTest.java @@ -1,4 +1,5 @@ import com.aserto.ChannelBuilder; +import com.aserto.directory.common.v3.ObjectDependency; import com.aserto.directory.v3.DirectoryClient; import com.aserto.directory.common.v3.Object; import com.aserto.directory.common.v3.ObjectIdentifier; @@ -13,12 +14,13 @@ import javax.net.ssl.SSLException; +import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; @Tag("IntegrationTest") @ExtendWith({IntegrationTestsExtenion.class}) @@ -140,4 +142,99 @@ void testGetRelations() { // Assert assertEquals(10, getRelationsResponse.getResultsList().size()); } + +// @Test +// @Tag("IntegrationTest") +// void testCheckRelationAdmin() { +// // Arrange & Act +// CheckRelationResponse checkRelationResponse = directoryClient.checkRelation( +// "group", +// "admin", +// "member", +// "user", +// "rick@the-citadel.com"); +// +// // Assert +// assertTrue(checkRelationResponse.getCheck()); +// } + + @Test + @Tag("IntegrationTest") + void testCheckRelationViewer() { + // Arrange & Act + CheckRelationResponse checkRelationResponse = directoryClient.checkRelation( + "group", + "viewer", + "member", + "user", + "rick@the-citadel.com"); + + // Assert + assertFalse(checkRelationResponse.getCheck()); + } + +// @Test +// @Tag("IntegrationTest") +// void testCheckAdmin() { +// // Arrange & Act +// CheckResponse checkResponse = directoryClient.check( +// "group", +// "admin", +// "member", +// "user", +// "rick@the-citadel.com"); +// +// // Assert +// assertTrue(checkResponse.getCheck()); +// } + + @Test + @Tag("IntegrationTest") + void testGetGraph() { + // Arrange + GetGraphRequest getGraphRequest = GetGraphRequest.newBuilder() + .setAnchorType("user") + .setAnchorId("rick@the-citadel.com") + .setObjectType("user") + .setObjectId("rick@the-citadel.com") + .build(); + + List objectDependencyList = Arrays.asList( + ObjectDependency.newBuilder() + .setObjectType("user") + .setObjectId("rick@the-citadel.com") + .setRelation("manager") + .setSubjectType("user") + .setSubjectId("beth@the-smiths.com") + .build(), + ObjectDependency.newBuilder() + .setObjectType("user") + .setObjectId("beth@the-smiths.com") + .setRelation("manager") + .setSubjectType("user") + .setSubjectId("jerry@the-smiths.com") + .build(), + ObjectDependency.newBuilder() + .setObjectType("user") + .setObjectId("rick@the-citadel.com") + .setRelation("manager") + .setSubjectType("user") + .setSubjectId("morty@the-citadel.com") + .build(), + ObjectDependency.newBuilder() + .setObjectType("user") + .setObjectId("rick@the-citadel.com") + .setRelation("manager") + .setSubjectType("user") + .setSubjectId("summer@the-smiths.com") + .build()); + + // Act + GetGraphResponse getGraphResponse = directoryClient.getGraph(getGraphRequest); + + // Assert + assertThat(getGraphResponse.getResultsList()) + .usingRecursiveFieldByFieldElementComparatorOnFields("objectId_", "objectType_", "relation_", "subjectId_", "subjectType_") + .containsExactlyInAnyOrderElementsOf(objectDependencyList); + } } From 5a0053baf2ec6b098ab3a2f9c831708786b4aeab Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Thu, 23 Nov 2023 12:12:03 +0200 Subject: [PATCH 20/26] Set manifest after topaz is started. --- src/test/java/DirectoryClientTest.java | 56 +++++++++++++------------- src/test/java/utils/Topaz.java | 19 ++++----- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/test/java/DirectoryClientTest.java b/src/test/java/DirectoryClientTest.java index e2c4f85..cd2364b 100644 --- a/src/test/java/DirectoryClientTest.java +++ b/src/test/java/DirectoryClientTest.java @@ -143,20 +143,20 @@ void testGetRelations() { assertEquals(10, getRelationsResponse.getResultsList().size()); } -// @Test -// @Tag("IntegrationTest") -// void testCheckRelationAdmin() { -// // Arrange & Act -// CheckRelationResponse checkRelationResponse = directoryClient.checkRelation( -// "group", -// "admin", -// "member", -// "user", -// "rick@the-citadel.com"); -// -// // Assert -// assertTrue(checkRelationResponse.getCheck()); -// } + @Test + @Tag("IntegrationTest") + void testCheckRelationAdmin() { + // Arrange & Act + CheckRelationResponse checkRelationResponse = directoryClient.checkRelation( + "group", + "admin", + "member", + "user", + "rick@the-citadel.com"); + + // Assert + assertTrue(checkRelationResponse.getCheck()); + } @Test @Tag("IntegrationTest") @@ -173,20 +173,20 @@ void testCheckRelationViewer() { assertFalse(checkRelationResponse.getCheck()); } -// @Test -// @Tag("IntegrationTest") -// void testCheckAdmin() { -// // Arrange & Act -// CheckResponse checkResponse = directoryClient.check( -// "group", -// "admin", -// "member", -// "user", -// "rick@the-citadel.com"); -// -// // Assert -// assertTrue(checkResponse.getCheck()); -// } + @Test + @Tag("IntegrationTest") + void testCheckAdmin() { + // Arrange & Act + CheckResponse checkResponse = directoryClient.check( + "group", + "admin", + "member", + "user", + "rick@the-citadel.com"); + + // Assert + assertTrue(checkResponse.getCheck()); + } @Test @Tag("IntegrationTest") diff --git a/src/test/java/utils/Topaz.java b/src/test/java/utils/Topaz.java index dd9d1ba..241cada 100644 --- a/src/test/java/utils/Topaz.java +++ b/src/test/java/utils/Topaz.java @@ -38,6 +38,7 @@ public void run() throws IOException, InterruptedException, URISyntaxException { backupCfg(); configure(); start(); + setManifest(); loadData(); } @@ -46,8 +47,17 @@ public void stop() throws IOException, InterruptedException { process.waitFor(); restoreDb(); restoreCfg(); + // delete temp directory used to store downloaded files deleteDirectory(new File("temp")); } + public void setManifest() throws IOException, URISyntaxException, InterruptedException { + downloadFile("https://raw.githubusercontent.com/aserto-dev/topaz/main/assets/citadel/manifest.yaml", "temp/manifest.yaml"); + + ProcessBuilder pb = new ProcessBuilder("topaz","manifest", "set", "-i", "temp/manifest.yaml"); + pb.inheritIO(); + Process process = pb.start(); + process.waitFor(); + } private void loadData() throws IOException, URISyntaxException, InterruptedException { downloadFile("https://raw.githubusercontent.com/aserto-dev/topaz/main/assets/citadel/citadel_objects.json", "temp/citadel_objects.json"); @@ -59,15 +69,6 @@ private void loadData() throws IOException, URISyntaxException, InterruptedExcep process.waitFor(); } - private void removeTempFile(String... files) { - for (String file: files) { - File tempFile = new File(file); - if(tempFile.exists()) { - tempFile.delete(); - } - } - } - private void deleteDirectory(File directoryToBeDeleted) { File[] allContents = directoryToBeDeleted.listFiles(); if (allContents != null) { From ab279d9a43f3a8b2b4cee85f20717b3bf71bf832 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Thu, 23 Nov 2023 15:15:25 +0200 Subject: [PATCH 21/26] Add setObjectTest. Update the setObject interface with optional fields. --- .../aserto/directory/v3/DirectoryClient.java | 5 +++++ .../directory/v3/DirectoryClientWriter.java | 1 + src/test/java/DirectoryClientTest.java | 20 +++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClient.java b/src/main/java/com/aserto/directory/v3/DirectoryClient.java index 1d9e285..8439723 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClient.java @@ -183,6 +183,11 @@ public GetGraphResponse getGraph(GetGraphRequest getGraphRequest) { return readerClient.getGraph(getGraphRequest); } + @Override + public SetObjectResponse setObject(String type, String id) { + return setObject(type, id, "", Struct.newBuilder().build(), ""); + } + @Override public SetObjectResponse setObject(String type, String id, String displayName, Struct properties, String hash) { Instant time = Instant.now(); diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java b/src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java index 99e5759..08401ff 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java @@ -7,6 +7,7 @@ import com.google.protobuf.Struct; public interface DirectoryClientWriter { + public SetObjectResponse setObject(String type, String id); public SetObjectResponse setObject(String type, String id, String displayName, Struct properties, String hash); public DeleteObjectResponse deleteObject(String type, String id); public DeleteObjectResponse deleteObject(String type, String id, boolean withRelations); diff --git a/src/test/java/DirectoryClientTest.java b/src/test/java/DirectoryClientTest.java index cd2364b..9d90151 100644 --- a/src/test/java/DirectoryClientTest.java +++ b/src/test/java/DirectoryClientTest.java @@ -5,6 +5,7 @@ import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.common.v3.Relation; import com.aserto.directory.reader.v3.*; +import com.aserto.directory.writer.v3.SetObjectResponse; import io.grpc.ManagedChannel; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; @@ -237,4 +238,23 @@ void testGetGraph() { .usingRecursiveFieldByFieldElementComparatorOnFields("objectId_", "objectType_", "relation_", "subjectId_", "subjectType_") .containsExactlyInAnyOrderElementsOf(objectDependencyList); } + + @Test + @Tag("IntegrationTest") + public void setObjectTest() { + // Arrange + Object object = Object.newBuilder() + .setType("test_type") + .setId("test_id") + .build(); + + // Act + SetObjectResponse setObjectResponse = directoryClient.setObject("test_type", "test_id"); + + // Assert + assertThat(setObjectResponse.getResult()) + .usingRecursiveComparison() + .comparingOnlyFields("type_", "id_") + .isEqualTo(object); + } } From ba8a6f0260ed29cc042e0939e5f72f6fe57f194d Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Fri, 24 Nov 2023 12:27:48 +0200 Subject: [PATCH 22/26] Remove set manifest ad import data from extension. Set manifest and import data before each integration tests. Extend the Directory writer and exporter interface. --- .../aserto/directory/v3/DirectoryClient.java | 31 ++ .../directory/v3/DirectoryClientExporter.java | 1 + .../directory/v3/DirectoryClientWriter.java | 4 + src/test/java/DirectoryClientTest.java | 405 ++++++++++++++---- src/test/java/utils/Topaz.java | 49 --- 5 files changed, 362 insertions(+), 128 deletions(-) diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClient.java b/src/main/java/com/aserto/directory/v3/DirectoryClient.java index 8439723..bed188c 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClient.java @@ -221,6 +221,19 @@ public DeleteObjectResponse deleteObject(String type, String id, boolean withRel .build()); } + @Override + public SetRelationResponse setRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId) { + Relation relation = Relation.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relationName) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .build(); + + return writerClient.setRelation(SetRelationRequest.newBuilder().setRelation(relation).build()); + } + @Override public SetRelationResponse setRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation) { Relation relation = Relation.newBuilder() @@ -250,6 +263,17 @@ public SetRelationResponse setRelation(String objectType, String objectId, Strin return writerClient.setRelation(SetRelationRequest.newBuilder().setRelation(relation).build()); } + @Override + public DeleteRelationResponse deleteRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId) { + return writerClient.deleteRelation(DeleteRelationRequest.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relationName) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .build()); + } + @Override public DeleteRelationResponse deleteRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation) { return writerClient.deleteRelation(DeleteRelationRequest.newBuilder() @@ -374,6 +398,13 @@ public void onCompleted() { } } + @Override + public Iterator exportData(Option options) { + return exporterClient.export(ExportRequest.newBuilder() + .setOptions(options.getNumber()) + .build()); + } + @Override public Iterator exportData(Option options, Timestamp startFrom) { return exporterClient.export(ExportRequest.newBuilder() diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java b/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java index 9633b86..b635eac 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java @@ -7,5 +7,6 @@ import java.util.Iterator; public interface DirectoryClientExporter { + public Iterator exportData(Option options); Iterator exportData(Option options, Timestamp startFrom); } diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java b/src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java index 08401ff..b07bebc 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientWriter.java @@ -11,10 +11,14 @@ public interface DirectoryClientWriter { public SetObjectResponse setObject(String type, String id, String displayName, Struct properties, String hash); public DeleteObjectResponse deleteObject(String type, String id); public DeleteObjectResponse deleteObject(String type, String id, boolean withRelations); + public SetRelationResponse setRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId); public SetRelationResponse setRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation); public SetRelationResponse setRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, String hash); + public DeleteRelationResponse deleteRelation(String objectType, String objectId, String relationName, + String subjectType, String subjectId); public DeleteRelationResponse deleteRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation); } diff --git a/src/test/java/DirectoryClientTest.java b/src/test/java/DirectoryClientTest.java index 9d90151..dac2f80 100644 --- a/src/test/java/DirectoryClientTest.java +++ b/src/test/java/DirectoryClientTest.java @@ -1,23 +1,26 @@ import com.aserto.ChannelBuilder; import com.aserto.directory.common.v3.ObjectDependency; +import com.aserto.directory.exporter.v3.ExportResponse; +import com.aserto.directory.exporter.v3.Option; +import com.aserto.directory.model.v3.GetManifestResponse; import com.aserto.directory.v3.DirectoryClient; import com.aserto.directory.common.v3.Object; import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.common.v3.Relation; import com.aserto.directory.reader.v3.*; +import com.aserto.directory.writer.v3.DeleteRelationResponse; import com.aserto.directory.writer.v3.SetObjectResponse; +import com.aserto.directory.writer.v3.SetRelationResponse; +import com.aserto.model.ImportElement; import io.grpc.ManagedChannel; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; +import io.grpc.StatusRuntimeException; +import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import utils.IntegrationTestsExtenion; import javax.net.ssl.SSLException; -import java.util.Arrays; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; @@ -28,8 +31,46 @@ class DirectoryClientTest { private static DirectoryClient directoryClient; + private final static String originalManifest = + "# yaml-language-server: $schema=https://www.topaz.sh/schema/manifest.json\n" + + "---\n" + + "\n" + + "### filename: manifest.yaml ###\n" + + "### datetime: 2023-10-17T00:00:00-00:00 ###\n" + + "### description: citadel manifest ###\n" + + "\n" + + "### model ###\n" + + "model:\n" + + " version: 3\n" + + "\n" + + "### object type definitions ###\n" + + "types:\n" + + " ### display_name: User ###\n" + + " user:\n" + + " relations:\n" + + " ### display_name: user#manager ###\n" + + " manager: user\n" + + "\n" + + " ### display_name: Identity ###\n" + + " identity:\n" + + " relations:\n" + + " ### display_name: identity#identifier ###\n" + + " identifier: user\n" + + "\n" + + " ### display_name: Group ###\n" + + " group:\n" + + " relations:\n" + + " ### display_name: group#member ###\n" + + " member: user\n\n"; + private final static String modifiedManifest = originalManifest + + " ### display_name: Department ###\n" + + " department:\n" + + " relations:\n" + + " ### display_name: group#member ###\n" + + " member: user\n"; + @BeforeAll - static void setDirectoryClient() throws SSLException { + static void setDirectoryClient() throws SSLException, InterruptedException { ManagedChannel channel = new ChannelBuilder() .withHost("localhost") .withPort(9292) @@ -39,27 +80,65 @@ static void setDirectoryClient() throws SSLException { directoryClient = new DirectoryClient(channel); } + @BeforeEach + void beforeEach() throws InterruptedException { + directoryClient.setManifest(originalManifest); + List list = importDataList(); + directoryClient.importData(list.stream()); + } + + @AfterEach + void afterEach() { + directoryClient.deleteManifest(); + } + @Test @Tag("IntegrationTest") void testGetUserWithNoRelations() { - // Arrange & Act - GetObjectResponse getObjectResponse = directoryClient.getObject("user", "morty@the-citadel.com"); + // Arrange + Object managerObject = Object.newBuilder() + .setType("user") + .setId("manager@aserto.com") + .build(); + + // Act + GetObjectResponse getObjectResponse = directoryClient.getObject("user", "manager@aserto.com"); // Assert - assertEquals("morty@the-citadel.com", getObjectResponse.getResult().getId()); + assertThat(getObjectResponse.getResult()) + .usingRecursiveComparison() + .comparingOnlyFields("objectType_", "objectId_") + .isEqualTo(managerObject); assertEquals(0, getObjectResponse.getRelationsList().size()); - } @Test @Tag("IntegrationTest") void testGetUserWithRelations() { - // Arrange & Act - GetObjectResponse getObjectResponse = directoryClient.getObject("user", "morty@the-citadel.com", true); + // Arrange + Object managerObject = Object.newBuilder() + .setType("user") + .setId("manager@aserto.com") + .build(); + Relation relation = Relation.newBuilder() + .setObjectType("user") + .setObjectId("user@aserto.com") + .setRelation("manager") + .setSubjectType("user") + .setSubjectId("manager@aserto.com") + .build(); + + // Act + GetObjectResponse getObjectResponse = directoryClient.getObject("user", "user@aserto.com", true); // Assert - assertEquals("morty@the-citadel.com", getObjectResponse.getResult().getId()); - assertEquals(4, getObjectResponse.getRelationsList().size()); + assertThat(getObjectResponse.getResult()) + .usingRecursiveComparison() + .comparingOnlyFields("objectType_", "objectId_") + .isEqualTo(managerObject); + assertThat(getObjectResponse.getRelationsList()) + .usingRecursiveFieldByFieldElementComparatorOnFields("objectId_", "objectType_", "relation_", "subjectId_", "subjectType_") + .containsExactlyInAnyOrderElementsOf(List.of(relation)); } @Test @@ -69,19 +148,19 @@ void testGetUsers() { GetObjectsResponse getObjectsResponse = directoryClient.getObjects("user"); // Assert - assertEquals(5, getObjectsResponse.getResultsList().size()); + assertEquals(2, getObjectsResponse.getResultsList().size()); } @Test @Tag("IntegrationTest") void testGetUsersWithLimit() { // Arrange & Act - GetObjectsResponse getObjectsResponse = directoryClient.getObjects("user", 2, ""); + GetObjectsResponse getObjectsResponse = directoryClient.getObjects("user", 1, ""); // Assert while (!getObjectsResponse.getPage().getNextToken().isEmpty()) { - assertTrue( getObjectsResponse.getResultsList().size() <= 2 ); - getObjectsResponse = directoryClient.getObjects("user", 2, getObjectsResponse.getPage().getNextToken()); + assertEquals(1, getObjectsResponse.getResultsList().size()); + getObjectsResponse = directoryClient.getObjects("user", 1, getObjectsResponse.getPage().getNextToken()); } } @@ -92,11 +171,11 @@ void testGetUserManyRequest() { List objects = List.of( ObjectIdentifier.newBuilder() .setObjectType("user") - .setObjectId("rick@the-citadel.com") + .setObjectId("manager@aserto.com") .build(), ObjectIdentifier.newBuilder() .setObjectType("user") - .setObjectId("morty@the-citadel.com") + .setObjectId("user@aserto.com") .build()); // Act @@ -113,47 +192,78 @@ void testGetUserManyRequest() { @Tag("IntegrationTest") void testGetRelation() { // Arrange + Relation expectedRelation = Relation.newBuilder() + .setObjectType("user") + .setObjectId("user@aserto.com") + .setRelation("manager") + .setSubjectType("user") + .setSubjectId("manager@aserto.com") + .build(); GetRelationResponse getRelationResponse = directoryClient.getRelation( - "group", - "editor", - "member", "user", - "morty@the-citadel.com"); + "user@aserto.com", + "manager", + "user", + "manager@aserto.com"); // Act Relation relation = getRelationResponse.getResult(); // Assert - assertEquals("group", relation.getObjectType()); - assertEquals("editor", relation.getObjectId()); - assertEquals("member", relation.getRelation()); - assertEquals("user", relation.getSubjectType()); - assertEquals("morty@the-citadel.com", relation.getSubjectId()); + assertThat(relation) + .usingRecursiveComparison() + .comparingOnlyFields("objectType_", "objectId_", "relation_", "subjectId_", "subjectType_") + .isEqualTo(expectedRelation); } @Test @Tag("IntegrationTest") void testGetRelations() { // Arrange - GetRelationsRequest getRelationsRequest = GetRelationsRequest.newBuilder().setObjectType("identity").build(); + Relation expectedManagerRelation = Relation.newBuilder() + .setObjectType("user") + .setObjectId("user@aserto.com") + .setRelation("manager") + .setSubjectType("user") + .setSubjectId("manager@aserto.com") + .build(); + Relation expectedFriendRelation = Relation.newBuilder() + .setObjectType("user") + .setObjectId("user@aserto.com") + .setRelation("friend") + .setSubjectType("user") + .setSubjectId("manager@aserto.com") + .build(); + + directoryClient.setRelation( + "user", + "user@aserto.com", + "friend", + "user", + "manager@aserto.com"); + + GetRelationsRequest getRelationsRequest = GetRelationsRequest.newBuilder().setObjectType("user").build(); // Act GetRelationsResponse getRelationsResponse = directoryClient.getRelations(getRelationsRequest); // Assert - assertEquals(10, getRelationsResponse.getResultsList().size()); + assertEquals(2, getRelationsResponse.getResultsList().size()); + assertThat(getRelationsResponse.getResultsList()) + .usingRecursiveFieldByFieldElementComparatorOnFields("objectId_", "objectType_", "relation_", "subjectId_", "subjectType_") + .containsExactlyInAnyOrderElementsOf(List.of(expectedManagerRelation, expectedFriendRelation)); } @Test @Tag("IntegrationTest") - void testCheckRelationAdmin() { + void testCheckRelationManager() { // Arrange & Act CheckRelationResponse checkRelationResponse = directoryClient.checkRelation( - "group", - "admin", - "member", "user", - "rick@the-citadel.com"); + "user@aserto.com", + "manager", + "user", + "manager@aserto.com"); // Assert assertTrue(checkRelationResponse.getCheck()); @@ -161,14 +271,14 @@ void testCheckRelationAdmin() { @Test @Tag("IntegrationTest") - void testCheckRelationViewer() { + void testCheckRelationFriend() { // Arrange & Act CheckRelationResponse checkRelationResponse = directoryClient.checkRelation( - "group", - "viewer", - "member", "user", - "rick@the-citadel.com"); + "user@aserto.com", + "friend", + "user", + "manager@aserto.com"); // Assert assertFalse(checkRelationResponse.getCheck()); @@ -176,14 +286,14 @@ void testCheckRelationViewer() { @Test @Tag("IntegrationTest") - void testCheckAdmin() { + void testCheckManager() { // Arrange & Act CheckResponse checkResponse = directoryClient.check( - "group", - "admin", - "member", "user", - "rick@the-citadel.com"); + "user@aserto.com", + "manager", + "user", + "manager@aserto.com"); // Assert assertTrue(checkResponse.getCheck()); @@ -195,40 +305,20 @@ void testGetGraph() { // Arrange GetGraphRequest getGraphRequest = GetGraphRequest.newBuilder() .setAnchorType("user") - .setAnchorId("rick@the-citadel.com") + .setAnchorId("user@aserto.com") .setObjectType("user") - .setObjectId("rick@the-citadel.com") + .setObjectId("user@aserto.com") .build(); - List objectDependencyList = Arrays.asList( - ObjectDependency.newBuilder() - .setObjectType("user") - .setObjectId("rick@the-citadel.com") - .setRelation("manager") - .setSubjectType("user") - .setSubjectId("beth@the-smiths.com") - .build(), - ObjectDependency.newBuilder() - .setObjectType("user") - .setObjectId("beth@the-smiths.com") - .setRelation("manager") - .setSubjectType("user") - .setSubjectId("jerry@the-smiths.com") - .build(), - ObjectDependency.newBuilder() - .setObjectType("user") - .setObjectId("rick@the-citadel.com") - .setRelation("manager") - .setSubjectType("user") - .setSubjectId("morty@the-citadel.com") - .build(), - ObjectDependency.newBuilder() - .setObjectType("user") - .setObjectId("rick@the-citadel.com") - .setRelation("manager") - .setSubjectType("user") - .setSubjectId("summer@the-smiths.com") - .build()); + List objectDependencyList = Arrays.asList( + ObjectDependency.newBuilder() + .setObjectType("user") + .setObjectId("user@aserto.com") + .setRelation("manager") + .setSubjectType("user") + .setSubjectId("manager@aserto.com") + .build() + ); // Act GetGraphResponse getGraphResponse = directoryClient.getGraph(getGraphRequest); @@ -241,7 +331,7 @@ void testGetGraph() { @Test @Tag("IntegrationTest") - public void setObjectTest() { + void setObjectTest() { // Arrange Object object = Object.newBuilder() .setType("test_type") @@ -257,4 +347,161 @@ public void setObjectTest() { .comparingOnlyFields("type_", "id_") .isEqualTo(object); } + + @Test + @Tag("IntegrationTest") + void deleteObjectTest() { + // Arrange + directoryClient.setObject("test_type", "test_id"); + assertEquals(1, directoryClient.getObjects("test_type").getResultsList().size()); + + // Act + directoryClient.deleteObject("test_type", "test_id"); + + // Assert + assertEquals(0, directoryClient.getObjects("test_type").getResultsList().size()); + } + + @Test + @Tag("IntegrationTest") + void setRelationTest() { + // Arrange + Relation relation = Relation.newBuilder() + .setObjectType("user") + .setObjectId("user@aserto.com") + .setRelation("friend") + .setSubjectType("user") + .setSubjectId("manager@aserto.com") + .build(); + + // Act + SetRelationResponse setRelationResponse = directoryClient.setRelation( + "user", + "user@aserto.com", + "friend", + "user", + "manager@aserto.com"); + + // Assert + assertThat(setRelationResponse.getResult()) + .usingRecursiveComparison() + .comparingOnlyFields("objectType_", "objectId_", "relation_", "subjectType_", "subjectId_") + .isEqualTo(relation); + } + + @Test + @Tag("IntegrationTest") + void deleteRelationTest() { + // Arrange & Act + DeleteRelationResponse deleteRelationResponse = directoryClient.deleteRelation( + "user", + "user@aserto.com", + "manager", + "user", + "manager@aserto.com"); + + // Assert + StatusRuntimeException exception = assertThrows(StatusRuntimeException.class, () -> { + directoryClient.getRelation( + "user", + "user@aserto.com", + "manager", + "user", + "manager@aserto.com"); + }); + + assertEquals("NOT_FOUND: E20051 key not found", exception.getMessage()); + } + + @Test + @Tag("IntegrationTest") + void testGetManifest() { + // Arrange & Act + GetManifestResponse getManifestResponse = directoryClient.getManifest(); + + // Assert + assertEquals(originalManifest, getManifestResponse.getBody().getData().toStringUtf8()); + } + + @Test + @Tag("IntegrationTest") + void testSetManifest() throws InterruptedException { + // Arrange & Act + directoryClient.setManifest(modifiedManifest); + GetManifestResponse getManifestResponse = directoryClient.getManifest(); + + // Assert + assertEquals(modifiedManifest, getManifestResponse.getBody().getData().toStringUtf8()); + } + + @Test + @Tag("IntegrationTest") + void testDeleteManifest() { + // Arrange & Act + directoryClient.deleteManifest(); + GetManifestResponse getManifestResponse = directoryClient.getManifest(); + + // Assert + assertEquals("", getManifestResponse.getBody().getData().toStringUtf8()); + } + + @Test + @Tag("IntegrationTest") + void importDataTest() throws InterruptedException { + // Arrange + List list = importDataList(); + List users = list.stream() + .map(ImportElement::getObject) + .filter(object -> object != null && object.getType().equals("user")) + .collect(Collectors.toList()); + + // Act + directoryClient.importData(list.stream()); + + // Assert + GetObjectsResponse getObjectsResponse = directoryClient.getObjects("user"); + assertThat(getObjectsResponse.getResultsList()) + .usingRecursiveFieldByFieldElementComparatorOnFields("objectId_", "objectType_", "relation_", "subjectId_", "subjectType_") + .containsAll(users); + + } + + @Test + @Tag("IntegrationTest") + void exportDataTest() throws InterruptedException { + // Arrange & Act + Iterator exportedData = directoryClient.exportData(Option.OPTION_DATA); + + // Assert + int elementCount = 0; + while(exportedData.hasNext()) { + exportedData.next(); + elementCount++; + } + + assertEquals(3, elementCount); + } + + private List importDataList() { + List importElements = new ArrayList<>(); + Object managerUser = Object.newBuilder() + .setType("user") + .setId("manager@aserto.com").build(); + Object user = Object.newBuilder() + .setType("user") + .setId("user@aserto.com").build(); + Relation managerRelation = Relation.newBuilder() + .setObjectType("user") + .setObjectId("user@aserto.com") + .setRelation("manager") + .setSubjectType("user") + .setSubjectId("manager@aserto.com") + .build(); + + importElements.add(new ImportElement(managerUser)); + importElements.add(new ImportElement(user)); + importElements.add(new ImportElement(managerRelation)); + + return importElements; + } } diff --git a/src/test/java/utils/Topaz.java b/src/test/java/utils/Topaz.java index 241cada..3d5aefb 100644 --- a/src/test/java/utils/Topaz.java +++ b/src/test/java/utils/Topaz.java @@ -5,16 +5,11 @@ import io.grpc.ManagedChannel; import javax.net.ssl.SSLException; -import java.io.BufferedInputStream; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.time.Duration; import java.util.concurrent.*; -import java.net.URI; public class Topaz { private String HOME_DIR = System.getProperty("user.home"); @@ -38,8 +33,6 @@ public void run() throws IOException, InterruptedException, URISyntaxException { backupCfg(); configure(); start(); - setManifest(); - loadData(); } public void stop() throws IOException, InterruptedException { @@ -47,48 +40,6 @@ public void stop() throws IOException, InterruptedException { process.waitFor(); restoreDb(); restoreCfg(); - // delete temp directory used to store downloaded files - deleteDirectory(new File("temp")); - } - public void setManifest() throws IOException, URISyntaxException, InterruptedException { - downloadFile("https://raw.githubusercontent.com/aserto-dev/topaz/main/assets/citadel/manifest.yaml", "temp/manifest.yaml"); - - ProcessBuilder pb = new ProcessBuilder("topaz","manifest", "set", "-i", "temp/manifest.yaml"); - pb.inheritIO(); - Process process = pb.start(); - process.waitFor(); - } - - private void loadData() throws IOException, URISyntaxException, InterruptedException { - downloadFile("https://raw.githubusercontent.com/aserto-dev/topaz/main/assets/citadel/citadel_objects.json", "temp/citadel_objects.json"); - downloadFile("https://raw.githubusercontent.com/aserto-dev/topaz/main/assets/citadel/citadel_relations.json", "temp/citadel_relations.json"); - - ProcessBuilder pb = new ProcessBuilder("topaz","import", "-i", "-d", "temp/"); - pb.inheritIO(); - Process process = pb.start(); - process.waitFor(); - } - - private void deleteDirectory(File directoryToBeDeleted) { - File[] allContents = directoryToBeDeleted.listFiles(); - if (allContents != null) { - for (File file : allContents) { - deleteDirectory(file); - } - } - directoryToBeDeleted.delete(); - } - - private void downloadFile(String url, String filePath) throws IOException, URISyntaxException { - Files.createDirectories(Paths.get(filePath).getParent()); - - BufferedInputStream in = new BufferedInputStream(new URI(url).toURL().openStream()); - FileOutputStream fileOutputStream = new FileOutputStream(filePath); - byte dataBuffer[] = new byte[1024]; - int bytesRead; - while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { - fileOutputStream.write(dataBuffer, 0, bytesRead); - } } private void start() throws IOException, InterruptedException { From d0fc13bbde3737cee01bfa61add8c43206bccab2 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Fri, 24 Nov 2023 17:35:56 +0200 Subject: [PATCH 23/26] Use citadel users instead of generic ones in integration tests. --- src/test/java/DirectoryClientTest.java | 140 +++++++++++++++---------- 1 file changed, 86 insertions(+), 54 deletions(-) diff --git a/src/test/java/DirectoryClientTest.java b/src/test/java/DirectoryClientTest.java index dac2f80..b951034 100644 --- a/src/test/java/DirectoryClientTest.java +++ b/src/test/java/DirectoryClientTest.java @@ -83,7 +83,7 @@ static void setDirectoryClient() throws SSLException, InterruptedException { @BeforeEach void beforeEach() throws InterruptedException { directoryClient.setManifest(originalManifest); - List list = importDataList(); + List list = importCitadelDataList(); directoryClient.importData(list.stream()); } @@ -98,11 +98,11 @@ void testGetUserWithNoRelations() { // Arrange Object managerObject = Object.newBuilder() .setType("user") - .setId("manager@aserto.com") + .setId("rick@the-citadel.com") .build(); // Act - GetObjectResponse getObjectResponse = directoryClient.getObject("user", "manager@aserto.com"); + GetObjectResponse getObjectResponse = directoryClient.getObject("user", "rick@the-citadel.com"); // Assert assertThat(getObjectResponse.getResult()) @@ -118,18 +118,25 @@ void testGetUserWithRelations() { // Arrange Object managerObject = Object.newBuilder() .setType("user") - .setId("manager@aserto.com") + .setId("rick@the-citadel.com") .build(); - Relation relation = Relation.newBuilder() + Relation managerRelation = Relation.newBuilder() .setObjectType("user") - .setObjectId("user@aserto.com") + .setObjectId("morty@the-citadel.com") .setRelation("manager") .setSubjectType("user") - .setSubjectId("manager@aserto.com") + .setSubjectId("rick@the-citadel.com") + .build(); + Relation adminRelation = Relation.newBuilder() + .setObjectType("group") + .setObjectId("admin") + .setRelation("member") + .setSubjectType("user") + .setSubjectId("rick@the-citadel.com") .build(); // Act - GetObjectResponse getObjectResponse = directoryClient.getObject("user", "user@aserto.com", true); + GetObjectResponse getObjectResponse = directoryClient.getObject("user", "rick@the-citadel.com", true); // Assert assertThat(getObjectResponse.getResult()) @@ -138,7 +145,7 @@ void testGetUserWithRelations() { .isEqualTo(managerObject); assertThat(getObjectResponse.getRelationsList()) .usingRecursiveFieldByFieldElementComparatorOnFields("objectId_", "objectType_", "relation_", "subjectId_", "subjectType_") - .containsExactlyInAnyOrderElementsOf(List.of(relation)); + .containsExactlyInAnyOrderElementsOf(List.of(managerRelation, adminRelation)); } @Test @@ -171,21 +178,20 @@ void testGetUserManyRequest() { List objects = List.of( ObjectIdentifier.newBuilder() .setObjectType("user") - .setObjectId("manager@aserto.com") + .setObjectId("rick@the-citadel.com") .build(), ObjectIdentifier.newBuilder() .setObjectType("user") - .setObjectId("user@aserto.com") + .setObjectId("morty@the-citadel.com") .build()); + Set expectedUsers = objects.stream().map(ObjectIdentifier::getObjectId).collect(Collectors.toSet()); // Act GetObjectManyResponse getObjectManyResponse = directoryClient.getObjectManyRequest(objects); // Assert Set actualUsers = getObjectManyResponse.getResultsList().stream().map(Object::getId).collect(Collectors.toSet()); - Set expectedUsers = objects.stream().map(ObjectIdentifier::getObjectId).collect(Collectors.toSet()); - - assertEquals(actualUsers, expectedUsers); + assertEquals(expectedUsers, actualUsers); } @Test @@ -194,17 +200,17 @@ void testGetRelation() { // Arrange Relation expectedRelation = Relation.newBuilder() .setObjectType("user") - .setObjectId("user@aserto.com") + .setObjectId("morty@the-citadel.com") .setRelation("manager") .setSubjectType("user") - .setSubjectId("manager@aserto.com") + .setSubjectId("rick@the-citadel.com") .build(); GetRelationResponse getRelationResponse = directoryClient.getRelation( "user", - "user@aserto.com", + "morty@the-citadel.com", "manager", "user", - "manager@aserto.com"); + "rick@the-citadel.com"); // Act Relation relation = getRelationResponse.getResult(); @@ -222,25 +228,25 @@ void testGetRelations() { // Arrange Relation expectedManagerRelation = Relation.newBuilder() .setObjectType("user") - .setObjectId("user@aserto.com") + .setObjectId("morty@the-citadel.com") .setRelation("manager") .setSubjectType("user") - .setSubjectId("manager@aserto.com") + .setSubjectId("rick@the-citadel.com") .build(); Relation expectedFriendRelation = Relation.newBuilder() .setObjectType("user") - .setObjectId("user@aserto.com") + .setObjectId("morty@the-citadel.com") .setRelation("friend") .setSubjectType("user") - .setSubjectId("manager@aserto.com") + .setSubjectId("rick@the-citadel.com") .build(); directoryClient.setRelation( "user", - "user@aserto.com", + "morty@the-citadel.com", "friend", "user", - "manager@aserto.com"); + "rick@the-citadel.com"); GetRelationsRequest getRelationsRequest = GetRelationsRequest.newBuilder().setObjectType("user").build(); @@ -260,10 +266,10 @@ void testCheckRelationManager() { // Arrange & Act CheckRelationResponse checkRelationResponse = directoryClient.checkRelation( "user", - "user@aserto.com", + "morty@the-citadel.com", "manager", "user", - "manager@aserto.com"); + "rick@the-citadel.com"); // Assert assertTrue(checkRelationResponse.getCheck()); @@ -275,10 +281,10 @@ void testCheckRelationFriend() { // Arrange & Act CheckRelationResponse checkRelationResponse = directoryClient.checkRelation( "user", - "user@aserto.com", + "morty@the-citadel.com", "friend", "user", - "manager@aserto.com"); + "rick@the-citadel.com"); // Assert assertFalse(checkRelationResponse.getCheck()); @@ -290,10 +296,10 @@ void testCheckManager() { // Arrange & Act CheckResponse checkResponse = directoryClient.check( "user", - "user@aserto.com", + "morty@the-citadel.com", "manager", "user", - "manager@aserto.com"); + "rick@the-citadel.com"); // Assert assertTrue(checkResponse.getCheck()); @@ -305,18 +311,18 @@ void testGetGraph() { // Arrange GetGraphRequest getGraphRequest = GetGraphRequest.newBuilder() .setAnchorType("user") - .setAnchorId("user@aserto.com") + .setAnchorId("morty@the-citadel.com") .setObjectType("user") - .setObjectId("user@aserto.com") + .setObjectId("morty@the-citadel.com") .build(); List objectDependencyList = Arrays.asList( ObjectDependency.newBuilder() .setObjectType("user") - .setObjectId("user@aserto.com") + .setObjectId("morty@the-citadel.com") .setRelation("manager") .setSubjectType("user") - .setSubjectId("manager@aserto.com") + .setSubjectId("rick@the-citadel.com") .build() ); @@ -368,19 +374,19 @@ void setRelationTest() { // Arrange Relation relation = Relation.newBuilder() .setObjectType("user") - .setObjectId("user@aserto.com") + .setObjectId("morty@the-citadel.com") .setRelation("friend") .setSubjectType("user") - .setSubjectId("manager@aserto.com") + .setSubjectId("rick@the-citadel.com") .build(); // Act SetRelationResponse setRelationResponse = directoryClient.setRelation( "user", - "user@aserto.com", + "morty@the-citadel.com", "friend", "user", - "manager@aserto.com"); + "rick@the-citadel.com"); // Assert assertThat(setRelationResponse.getResult()) @@ -395,19 +401,19 @@ void deleteRelationTest() { // Arrange & Act DeleteRelationResponse deleteRelationResponse = directoryClient.deleteRelation( "user", - "user@aserto.com", + "morty@the-citadel.com", "manager", "user", - "manager@aserto.com"); + "rick@the-citadel.com"); // Assert StatusRuntimeException exception = assertThrows(StatusRuntimeException.class, () -> { directoryClient.getRelation( "user", - "user@aserto.com", + "morty@the-citadel.com", "manager", "user", - "manager@aserto.com"); + "rick@the-citadel.com"); }); assertEquals("NOT_FOUND: E20051 key not found", exception.getMessage()); @@ -449,7 +455,7 @@ void testDeleteManifest() { @Tag("IntegrationTest") void importDataTest() throws InterruptedException { // Arrange - List list = importDataList(); + List list = importCitadelDataList(); List users = list.stream() .map(ImportElement::getObject) .filter(object -> object != null && object.getType().equals("user")) @@ -468,7 +474,7 @@ void importDataTest() throws InterruptedException { @Test @Tag("IntegrationTest") - void exportDataTest() throws InterruptedException { + void exportDataTest() { // Arrange & Act Iterator exportedData = directoryClient.exportData(Option.OPTION_DATA); @@ -479,27 +485,53 @@ void exportDataTest() throws InterruptedException { elementCount++; } - assertEquals(3, elementCount); + assertEquals(7, elementCount); } - private List importDataList() { + private List importCitadelDataList() { List importElements = new ArrayList<>(); - Object managerUser = Object.newBuilder() + Object rick = Object.newBuilder() .setType("user") - .setId("manager@aserto.com").build(); - Object user = Object.newBuilder() + .setId("rick@the-citadel.com").build(); + Object morty = Object.newBuilder() .setType("user") - .setId("user@aserto.com").build(); + .setId("morty@the-citadel.com").build(); + Object adminGroup = Object.newBuilder() + .setType("group") + .setId("admin") + .build(); + Object editorGroup = Object.newBuilder() + .setType("group") + .setId("editor") + .build(); + Relation rickAdminRelation = Relation.newBuilder() + .setObjectType("group") + .setObjectId("admin") + .setRelation("member") + .setSubjectType("user") + .setSubjectId("rick@the-citadel.com") + .build(); + Relation mortyEditorRelation = Relation.newBuilder() + .setObjectType("group") + .setObjectId("editor") + .setRelation("member") + .setSubjectType("user") + .setSubjectId("morty@the-citadel.com") + .build(); Relation managerRelation = Relation.newBuilder() .setObjectType("user") - .setObjectId("user@aserto.com") + .setObjectId("morty@the-citadel.com") .setRelation("manager") .setSubjectType("user") - .setSubjectId("manager@aserto.com") + .setSubjectId("rick@the-citadel.com") .build(); - importElements.add(new ImportElement(managerUser)); - importElements.add(new ImportElement(user)); + importElements.add(new ImportElement(rick)); + importElements.add(new ImportElement(morty)); + importElements.add(new ImportElement(adminGroup)); + importElements.add(new ImportElement(editorGroup)); + importElements.add(new ImportElement(rickAdminRelation)); + importElements.add(new ImportElement(mortyEditorRelation)); importElements.add(new ImportElement(managerRelation)); return importElements; From ef30768c0a685070fbf6ac0e00df1d0bd46dd13c Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Mon, 27 Nov 2023 11:31:23 +0200 Subject: [PATCH 24/26] Fix linting errors. --- .../aserto/directory/v3/DirectoryClient.java | 2 +- .../directory/v3/DirectoryClientExporter.java | 2 +- .../directory/v3/DirectoryClientModel.java | 6 ++-- .../directory/v3/DirectoryClientReader.java | 32 +++++++++---------- src/test/java/AuthzClientIntegrationTest.java | 3 -- src/test/java/DirectoryClientTest.java | 20 ------------ .../java/utils/IntegrationTestsExtenion.java | 2 +- 7 files changed, 22 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClient.java b/src/main/java/com/aserto/directory/v3/DirectoryClient.java index bed188c..b34cbe9 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClient.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClient.java @@ -108,6 +108,7 @@ public GetRelationResponse getRelation(String objectType, String objectId, Strin public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation) { return getRelation(objectType, objectId, relationName, subjectType, subjectId, subjectRelation, false); } + @Override public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects) { return readerClient.getRelation(GetRelationRequest.newBuilder() @@ -177,7 +178,6 @@ public CheckResponse check(String objectType, String objectId, String relationNa .build()); } - @Override public GetGraphResponse getGraph(GetGraphRequest getGraphRequest) { return readerClient.getGraph(getGraphRequest); diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java b/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java index b635eac..fd5c6e3 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientExporter.java @@ -7,6 +7,6 @@ import java.util.Iterator; public interface DirectoryClientExporter { - public Iterator exportData(Option options); + Iterator exportData(Option options); Iterator exportData(Option options, Timestamp startFrom); } diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClientModel.java b/src/main/java/com/aserto/directory/v3/DirectoryClientModel.java index b3581fb..763c320 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClientModel.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientModel.java @@ -4,7 +4,7 @@ import com.aserto.directory.model.v3.GetManifestResponse; public interface DirectoryClientModel { - public GetManifestResponse getManifest(); - public void setManifest(String manifest) throws InterruptedException; - public DeleteManifestResponse deleteManifest(); + GetManifestResponse getManifest(); + void setManifest(String manifest) throws InterruptedException; + DeleteManifestResponse deleteManifest(); } diff --git a/src/main/java/com/aserto/directory/v3/DirectoryClientReader.java b/src/main/java/com/aserto/directory/v3/DirectoryClientReader.java index bd3a20b..5a5b541 100644 --- a/src/main/java/com/aserto/directory/v3/DirectoryClientReader.java +++ b/src/main/java/com/aserto/directory/v3/DirectoryClientReader.java @@ -6,28 +6,28 @@ import java.util.List; public interface DirectoryClientReader { - public GetObjectResponse getObject(String type, String id); - public GetObjectResponse getObject(String type, String id, boolean withRelations); - public GetObjectsResponse getObjects(String type); - public GetObjectsResponse getObjects(String type, int pageSize, String pageToken); - public GetObjectManyResponse getObjectManyRequest(List objectIdentifiers); - public GetRelationResponse getRelation(String objectType, String objectId, String relationName, + GetObjectResponse getObject(String type, String id); + GetObjectResponse getObject(String type, String id, boolean withRelations); + GetObjectsResponse getObjects(String type); + GetObjectsResponse getObjects(String type, int pageSize, String pageToken); + GetObjectManyResponse getObjectManyRequest(List objectIdentifiers); + GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId); - public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, + GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation); - public GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, + GetRelationResponse getRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, String subjectRelation, boolean withObjects); - public GetRelationsResponse getRelations(GetRelationsRequest relationsRequest); + GetRelationsResponse getRelations(GetRelationsRequest relationsRequest); - public CheckPermissionResponse checkPermission(String objectType, String objectId, String subjectType, + CheckPermissionResponse checkPermission(String objectType, String objectId, String subjectType, String subjectId, String permissionName); - public CheckPermissionResponse checkPermission(String objectType, String objectId, + CheckPermissionResponse checkPermission(String objectType, String objectId, String subjectType, String subjectId, String permissionName, boolean trace); - public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId); - public CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, + CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId); + CheckRelationResponse checkRelation(String objectType, String objectId, String relationName, String subjectType, String subjectId, boolean trace); - public CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId); - public CheckResponse check(String objectType, String objectId, String relationName, + CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId); + CheckResponse check(String objectType, String objectId, String relationName, String subjectType, String subjectId, boolean trace); - public GetGraphResponse getGraph(GetGraphRequest getGraphRequest); + GetGraphResponse getGraph(GetGraphRequest getGraphRequest); } diff --git a/src/test/java/AuthzClientIntegrationTest.java b/src/test/java/AuthzClientIntegrationTest.java index e66c549..772a063 100644 --- a/src/test/java/AuthzClientIntegrationTest.java +++ b/src/test/java/AuthzClientIntegrationTest.java @@ -19,7 +19,6 @@ @ExtendWith({IntegrationTestsExtenion.class}) class AuthzClientIntegrationTest { @Test - @Tag("IntegrationTest") void testBuildAuthzClient() throws IOException { // Arrange ManagedChannel channel = new ChannelBuilder() @@ -40,7 +39,6 @@ void testBuildAuthzClient() throws IOException { } @Test - @Tag("IntegrationTest") void testInsecureConnectionToInsecureClient() throws SSLException { // Arrange ManagedChannel channel = new ChannelBuilder() @@ -60,7 +58,6 @@ void testInsecureConnectionToInsecureClient() throws SSLException { } @Test - @Tag("IntegrationTest") void testFailWhenSecureConnectionToInsecureClient() throws SSLException { // Arrange ManagedChannel channel = new ChannelBuilder() diff --git a/src/test/java/DirectoryClientTest.java b/src/test/java/DirectoryClientTest.java index b951034..1cd05ed 100644 --- a/src/test/java/DirectoryClientTest.java +++ b/src/test/java/DirectoryClientTest.java @@ -93,7 +93,6 @@ void afterEach() { } @Test - @Tag("IntegrationTest") void testGetUserWithNoRelations() { // Arrange Object managerObject = Object.newBuilder() @@ -113,7 +112,6 @@ void testGetUserWithNoRelations() { } @Test - @Tag("IntegrationTest") void testGetUserWithRelations() { // Arrange Object managerObject = Object.newBuilder() @@ -149,7 +147,6 @@ void testGetUserWithRelations() { } @Test - @Tag("IntegrationTest") void testGetUsers() { // Arrange & Act GetObjectsResponse getObjectsResponse = directoryClient.getObjects("user"); @@ -159,7 +156,6 @@ void testGetUsers() { } @Test - @Tag("IntegrationTest") void testGetUsersWithLimit() { // Arrange & Act GetObjectsResponse getObjectsResponse = directoryClient.getObjects("user", 1, ""); @@ -172,7 +168,6 @@ void testGetUsersWithLimit() { } @Test - @Tag("IntegrationTest") void testGetUserManyRequest() { // Arrange List objects = List.of( @@ -195,7 +190,6 @@ void testGetUserManyRequest() { } @Test - @Tag("IntegrationTest") void testGetRelation() { // Arrange Relation expectedRelation = Relation.newBuilder() @@ -223,7 +217,6 @@ void testGetRelation() { } @Test - @Tag("IntegrationTest") void testGetRelations() { // Arrange Relation expectedManagerRelation = Relation.newBuilder() @@ -261,7 +254,6 @@ void testGetRelations() { } @Test - @Tag("IntegrationTest") void testCheckRelationManager() { // Arrange & Act CheckRelationResponse checkRelationResponse = directoryClient.checkRelation( @@ -276,7 +268,6 @@ void testCheckRelationManager() { } @Test - @Tag("IntegrationTest") void testCheckRelationFriend() { // Arrange & Act CheckRelationResponse checkRelationResponse = directoryClient.checkRelation( @@ -291,7 +282,6 @@ void testCheckRelationFriend() { } @Test - @Tag("IntegrationTest") void testCheckManager() { // Arrange & Act CheckResponse checkResponse = directoryClient.check( @@ -306,7 +296,6 @@ void testCheckManager() { } @Test - @Tag("IntegrationTest") void testGetGraph() { // Arrange GetGraphRequest getGraphRequest = GetGraphRequest.newBuilder() @@ -336,7 +325,6 @@ void testGetGraph() { } @Test - @Tag("IntegrationTest") void setObjectTest() { // Arrange Object object = Object.newBuilder() @@ -355,7 +343,6 @@ void setObjectTest() { } @Test - @Tag("IntegrationTest") void deleteObjectTest() { // Arrange directoryClient.setObject("test_type", "test_id"); @@ -369,7 +356,6 @@ void deleteObjectTest() { } @Test - @Tag("IntegrationTest") void setRelationTest() { // Arrange Relation relation = Relation.newBuilder() @@ -396,7 +382,6 @@ void setRelationTest() { } @Test - @Tag("IntegrationTest") void deleteRelationTest() { // Arrange & Act DeleteRelationResponse deleteRelationResponse = directoryClient.deleteRelation( @@ -420,7 +405,6 @@ void deleteRelationTest() { } @Test - @Tag("IntegrationTest") void testGetManifest() { // Arrange & Act GetManifestResponse getManifestResponse = directoryClient.getManifest(); @@ -430,7 +414,6 @@ void testGetManifest() { } @Test - @Tag("IntegrationTest") void testSetManifest() throws InterruptedException { // Arrange & Act directoryClient.setManifest(modifiedManifest); @@ -441,7 +424,6 @@ void testSetManifest() throws InterruptedException { } @Test - @Tag("IntegrationTest") void testDeleteManifest() { // Arrange & Act directoryClient.deleteManifest(); @@ -452,7 +434,6 @@ void testDeleteManifest() { } @Test - @Tag("IntegrationTest") void importDataTest() throws InterruptedException { // Arrange List list = importCitadelDataList(); @@ -473,7 +454,6 @@ void importDataTest() throws InterruptedException { } @Test - @Tag("IntegrationTest") void exportDataTest() { // Arrange & Act Iterator exportedData = directoryClient.exportData(Option.OPTION_DATA); diff --git a/src/test/java/utils/IntegrationTestsExtenion.java b/src/test/java/utils/IntegrationTestsExtenion.java index 1ff0cfa..99564cd 100644 --- a/src/test/java/utils/IntegrationTestsExtenion.java +++ b/src/test/java/utils/IntegrationTestsExtenion.java @@ -32,4 +32,4 @@ public void beforeAll(ExtensionContext context) throws IOException, InterruptedE public void close() throws IOException, InterruptedException { topaz.stop(); } -} \ No newline at end of file +} From f811ad5b60e1ee0b3a8ce60708c3d80e2c5e3946 Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Mon, 27 Nov 2023 17:21:19 +0200 Subject: [PATCH 25/26] Add factory for directory objects, relations and object identifiers. --- .../java/org/example/DirectoryExample.java | 13 +- .../java/com/aserto/directory/v3/Factory.java | 26 ++++ src/test/java/DirectoryClientTest.java | 122 ++++-------------- 3 files changed, 52 insertions(+), 109 deletions(-) create mode 100644 src/main/java/com/aserto/directory/v3/Factory.java diff --git a/examples/directory-example/src/main/java/org/example/DirectoryExample.java b/examples/directory-example/src/main/java/org/example/DirectoryExample.java index d84faf8..032db89 100644 --- a/examples/directory-example/src/main/java/org/example/DirectoryExample.java +++ b/examples/directory-example/src/main/java/org/example/DirectoryExample.java @@ -1,11 +1,12 @@ package org.example; import com.aserto.ChannelBuilder; -import com.aserto.directory.DirectoryClient; +import com.aserto.directory.v3.DirectoryClient; import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.reader.v3.GetObjectManyResponse; import com.aserto.directory.reader.v3.GetObjectResponse; import com.aserto.directory.reader.v3.GetObjectsResponse; +import com.aserto.directory.v3.Factory; import io.grpc.ManagedChannel; import javax.net.ssl.SSLException; @@ -43,14 +44,8 @@ public static void getUsersExample(DirectoryClient directoryClient) { public static void getObjectManyRequest(DirectoryClient directoryClient) { System.out.println("------ Get object many example ------"); List objects = List.of( - ObjectIdentifier.newBuilder() - .setObjectType("user") - .setObjectId("rick@the-citadel.com") - .build(), - ObjectIdentifier.newBuilder() - .setObjectType("user") - .setObjectId("morty@the-citadel.com") - .build()); + Factory.buildObjectIdentifier("user", "rick@the-citadel.com"), + Factory.buildObjectIdentifier("user", "morty@the-citadel.com")); GetObjectManyResponse getObjectManyRequest = directoryClient.getObjectManyRequest(objects); System.out.println(getObjectManyRequest); diff --git a/src/main/java/com/aserto/directory/v3/Factory.java b/src/main/java/com/aserto/directory/v3/Factory.java new file mode 100644 index 0000000..eccdf40 --- /dev/null +++ b/src/main/java/com/aserto/directory/v3/Factory.java @@ -0,0 +1,26 @@ +package com.aserto.directory.v3; + +import com.aserto.directory.common.v3.Object; +import com.aserto.directory.common.v3.ObjectIdentifier; +import com.aserto.directory.common.v3.Relation; + +public class Factory { + + public static Object buildObject(String type, String id) { + return Object.newBuilder().setType(type).setId(id).build(); + } + + public static ObjectIdentifier buildObjectIdentifier(String type, String id) { + return ObjectIdentifier.newBuilder().setObjectType(type).setObjectId(id).build(); + } + + public static Relation buildRelation(String objectType, String objectId, String relation, String subjectType, String subjectId) { + return Relation.newBuilder() + .setObjectType(objectType) + .setObjectId(objectId) + .setRelation(relation) + .setSubjectType(subjectType) + .setSubjectId(subjectId) + .build(); + } +} diff --git a/src/test/java/DirectoryClientTest.java b/src/test/java/DirectoryClientTest.java index 1cd05ed..3ff6d2f 100644 --- a/src/test/java/DirectoryClientTest.java +++ b/src/test/java/DirectoryClientTest.java @@ -8,6 +8,7 @@ import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.common.v3.Relation; import com.aserto.directory.reader.v3.*; +import com.aserto.directory.v3.Factory; import com.aserto.directory.writer.v3.DeleteRelationResponse; import com.aserto.directory.writer.v3.SetObjectResponse; import com.aserto.directory.writer.v3.SetRelationResponse; @@ -95,10 +96,7 @@ void afterEach() { @Test void testGetUserWithNoRelations() { // Arrange - Object managerObject = Object.newBuilder() - .setType("user") - .setId("rick@the-citadel.com") - .build(); + Object managerObject = Factory.buildObject("user", "rick@the-citadel.com"); // Act GetObjectResponse getObjectResponse = directoryClient.getObject("user", "rick@the-citadel.com"); @@ -114,24 +112,9 @@ void testGetUserWithNoRelations() { @Test void testGetUserWithRelations() { // Arrange - Object managerObject = Object.newBuilder() - .setType("user") - .setId("rick@the-citadel.com") - .build(); - Relation managerRelation = Relation.newBuilder() - .setObjectType("user") - .setObjectId("morty@the-citadel.com") - .setRelation("manager") - .setSubjectType("user") - .setSubjectId("rick@the-citadel.com") - .build(); - Relation adminRelation = Relation.newBuilder() - .setObjectType("group") - .setObjectId("admin") - .setRelation("member") - .setSubjectType("user") - .setSubjectId("rick@the-citadel.com") - .build(); + Object managerObject = Factory.buildObject("user", "rick@the-citadel.com"); + Relation managerRelation = Factory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); + Relation adminRelation = Factory.buildRelation("group", "admin", "member", "user", "rick@the-citadel.com"); // Act GetObjectResponse getObjectResponse = directoryClient.getObject("user", "rick@the-citadel.com", true); @@ -171,14 +154,8 @@ void testGetUsersWithLimit() { void testGetUserManyRequest() { // Arrange List objects = List.of( - ObjectIdentifier.newBuilder() - .setObjectType("user") - .setObjectId("rick@the-citadel.com") - .build(), - ObjectIdentifier.newBuilder() - .setObjectType("user") - .setObjectId("morty@the-citadel.com") - .build()); + Factory.buildObjectIdentifier("user", "rick@the-citadel.com"), + Factory.buildObjectIdentifier("user", "morty@the-citadel.com")); Set expectedUsers = objects.stream().map(ObjectIdentifier::getObjectId).collect(Collectors.toSet()); // Act @@ -192,13 +169,9 @@ void testGetUserManyRequest() { @Test void testGetRelation() { // Arrange - Relation expectedRelation = Relation.newBuilder() - .setObjectType("user") - .setObjectId("morty@the-citadel.com") - .setRelation("manager") - .setSubjectType("user") - .setSubjectId("rick@the-citadel.com") - .build(); + Relation expectedRelation = Factory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); + + // Act GetRelationResponse getRelationResponse = directoryClient.getRelation( "user", "morty@the-citadel.com", @@ -206,10 +179,8 @@ void testGetRelation() { "user", "rick@the-citadel.com"); - // Act - Relation relation = getRelationResponse.getResult(); - // Assert + Relation relation = getRelationResponse.getResult(); assertThat(relation) .usingRecursiveComparison() .comparingOnlyFields("objectType_", "objectId_", "relation_", "subjectId_", "subjectType_") @@ -219,20 +190,8 @@ void testGetRelation() { @Test void testGetRelations() { // Arrange - Relation expectedManagerRelation = Relation.newBuilder() - .setObjectType("user") - .setObjectId("morty@the-citadel.com") - .setRelation("manager") - .setSubjectType("user") - .setSubjectId("rick@the-citadel.com") - .build(); - Relation expectedFriendRelation = Relation.newBuilder() - .setObjectType("user") - .setObjectId("morty@the-citadel.com") - .setRelation("friend") - .setSubjectType("user") - .setSubjectId("rick@the-citadel.com") - .build(); + Relation expectedManagerRelation = Factory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); + Relation expectedFriendRelation = Factory.buildRelation("user", "morty@the-citadel.com", "friend", "user", "rick@the-citadel.com"); directoryClient.setRelation( "user", @@ -327,10 +286,7 @@ void testGetGraph() { @Test void setObjectTest() { // Arrange - Object object = Object.newBuilder() - .setType("test_type") - .setId("test_id") - .build(); + Object object = Factory.buildObject("test_type", "test_id"); // Act SetObjectResponse setObjectResponse = directoryClient.setObject("test_type", "test_id"); @@ -358,13 +314,7 @@ void deleteObjectTest() { @Test void setRelationTest() { // Arrange - Relation relation = Relation.newBuilder() - .setObjectType("user") - .setObjectId("morty@the-citadel.com") - .setRelation("friend") - .setSubjectType("user") - .setSubjectId("rick@the-citadel.com") - .build(); + Relation relation = Factory.buildRelation("user", "morty@the-citadel.com", "friend", "user", "rick@the-citadel.com"); // Act SetRelationResponse setRelationResponse = directoryClient.setRelation( @@ -470,41 +420,13 @@ void exportDataTest() { private List importCitadelDataList() { List importElements = new ArrayList<>(); - Object rick = Object.newBuilder() - .setType("user") - .setId("rick@the-citadel.com").build(); - Object morty = Object.newBuilder() - .setType("user") - .setId("morty@the-citadel.com").build(); - Object adminGroup = Object.newBuilder() - .setType("group") - .setId("admin") - .build(); - Object editorGroup = Object.newBuilder() - .setType("group") - .setId("editor") - .build(); - Relation rickAdminRelation = Relation.newBuilder() - .setObjectType("group") - .setObjectId("admin") - .setRelation("member") - .setSubjectType("user") - .setSubjectId("rick@the-citadel.com") - .build(); - Relation mortyEditorRelation = Relation.newBuilder() - .setObjectType("group") - .setObjectId("editor") - .setRelation("member") - .setSubjectType("user") - .setSubjectId("morty@the-citadel.com") - .build(); - Relation managerRelation = Relation.newBuilder() - .setObjectType("user") - .setObjectId("morty@the-citadel.com") - .setRelation("manager") - .setSubjectType("user") - .setSubjectId("rick@the-citadel.com") - .build(); + Object rick = Factory.buildObject("user", "rick@the-citadel.com"); + Object morty = Factory.buildObject("user", "morty@the-citadel.com"); + Object adminGroup = Factory.buildObject("group", "admin"); + Object editorGroup = Factory.buildObject("group", "editor"); + Relation rickAdminRelation = Factory.buildRelation("group", "admin", "member", "user", "rick@the-citadel.com"); + Relation mortyEditorRelation = Factory.buildRelation("group", "editor", "member", "user", "morty@the-citadel.com"); + Relation managerRelation = Factory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); importElements.add(new ImportElement(rick)); importElements.add(new ImportElement(morty)); From 388027461ed02ab5a0f862ca2fca0ebdcdea578c Mon Sep 17 00:00:00 2001 From: Bogdan Irimie Date: Tue, 28 Nov 2023 15:23:59 +0200 Subject: [PATCH 26/26] Rename Factory to Directory --- .../java/org/example/DirectoryExample.java | 6 +-- .../v3/{Factory.java => Directory.java} | 2 +- src/test/java/DirectoryClientTest.java | 38 +++++++++---------- 3 files changed, 23 insertions(+), 23 deletions(-) rename src/main/java/com/aserto/directory/v3/{Factory.java => Directory.java} (97%) diff --git a/examples/directory-example/src/main/java/org/example/DirectoryExample.java b/examples/directory-example/src/main/java/org/example/DirectoryExample.java index 032db89..4874f83 100644 --- a/examples/directory-example/src/main/java/org/example/DirectoryExample.java +++ b/examples/directory-example/src/main/java/org/example/DirectoryExample.java @@ -6,7 +6,7 @@ import com.aserto.directory.reader.v3.GetObjectManyResponse; import com.aserto.directory.reader.v3.GetObjectResponse; import com.aserto.directory.reader.v3.GetObjectsResponse; -import com.aserto.directory.v3.Factory; +import com.aserto.directory.v3.Directory; import io.grpc.ManagedChannel; import javax.net.ssl.SSLException; @@ -44,8 +44,8 @@ public static void getUsersExample(DirectoryClient directoryClient) { public static void getObjectManyRequest(DirectoryClient directoryClient) { System.out.println("------ Get object many example ------"); List objects = List.of( - Factory.buildObjectIdentifier("user", "rick@the-citadel.com"), - Factory.buildObjectIdentifier("user", "morty@the-citadel.com")); + Directory.buildObjectIdentifier("user", "rick@the-citadel.com"), + Directory.buildObjectIdentifier("user", "morty@the-citadel.com")); GetObjectManyResponse getObjectManyRequest = directoryClient.getObjectManyRequest(objects); System.out.println(getObjectManyRequest); diff --git a/src/main/java/com/aserto/directory/v3/Factory.java b/src/main/java/com/aserto/directory/v3/Directory.java similarity index 97% rename from src/main/java/com/aserto/directory/v3/Factory.java rename to src/main/java/com/aserto/directory/v3/Directory.java index eccdf40..a23b154 100644 --- a/src/main/java/com/aserto/directory/v3/Factory.java +++ b/src/main/java/com/aserto/directory/v3/Directory.java @@ -4,7 +4,7 @@ import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.common.v3.Relation; -public class Factory { +public class Directory { public static Object buildObject(String type, String id) { return Object.newBuilder().setType(type).setId(id).build(); diff --git a/src/test/java/DirectoryClientTest.java b/src/test/java/DirectoryClientTest.java index 3ff6d2f..bd654bf 100644 --- a/src/test/java/DirectoryClientTest.java +++ b/src/test/java/DirectoryClientTest.java @@ -3,12 +3,12 @@ import com.aserto.directory.exporter.v3.ExportResponse; import com.aserto.directory.exporter.v3.Option; import com.aserto.directory.model.v3.GetManifestResponse; +import com.aserto.directory.v3.Directory; import com.aserto.directory.v3.DirectoryClient; import com.aserto.directory.common.v3.Object; import com.aserto.directory.common.v3.ObjectIdentifier; import com.aserto.directory.common.v3.Relation; import com.aserto.directory.reader.v3.*; -import com.aserto.directory.v3.Factory; import com.aserto.directory.writer.v3.DeleteRelationResponse; import com.aserto.directory.writer.v3.SetObjectResponse; import com.aserto.directory.writer.v3.SetRelationResponse; @@ -96,7 +96,7 @@ void afterEach() { @Test void testGetUserWithNoRelations() { // Arrange - Object managerObject = Factory.buildObject("user", "rick@the-citadel.com"); + Object managerObject = Directory.buildObject("user", "rick@the-citadel.com"); // Act GetObjectResponse getObjectResponse = directoryClient.getObject("user", "rick@the-citadel.com"); @@ -112,9 +112,9 @@ void testGetUserWithNoRelations() { @Test void testGetUserWithRelations() { // Arrange - Object managerObject = Factory.buildObject("user", "rick@the-citadel.com"); - Relation managerRelation = Factory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); - Relation adminRelation = Factory.buildRelation("group", "admin", "member", "user", "rick@the-citadel.com"); + Object managerObject = Directory.buildObject("user", "rick@the-citadel.com"); + Relation managerRelation = Directory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); + Relation adminRelation = Directory.buildRelation("group", "admin", "member", "user", "rick@the-citadel.com"); // Act GetObjectResponse getObjectResponse = directoryClient.getObject("user", "rick@the-citadel.com", true); @@ -154,8 +154,8 @@ void testGetUsersWithLimit() { void testGetUserManyRequest() { // Arrange List objects = List.of( - Factory.buildObjectIdentifier("user", "rick@the-citadel.com"), - Factory.buildObjectIdentifier("user", "morty@the-citadel.com")); + Directory.buildObjectIdentifier("user", "rick@the-citadel.com"), + Directory.buildObjectIdentifier("user", "morty@the-citadel.com")); Set expectedUsers = objects.stream().map(ObjectIdentifier::getObjectId).collect(Collectors.toSet()); // Act @@ -169,7 +169,7 @@ void testGetUserManyRequest() { @Test void testGetRelation() { // Arrange - Relation expectedRelation = Factory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); + Relation expectedRelation = Directory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); // Act GetRelationResponse getRelationResponse = directoryClient.getRelation( @@ -190,8 +190,8 @@ void testGetRelation() { @Test void testGetRelations() { // Arrange - Relation expectedManagerRelation = Factory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); - Relation expectedFriendRelation = Factory.buildRelation("user", "morty@the-citadel.com", "friend", "user", "rick@the-citadel.com"); + Relation expectedManagerRelation = Directory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); + Relation expectedFriendRelation = Directory.buildRelation("user", "morty@the-citadel.com", "friend", "user", "rick@the-citadel.com"); directoryClient.setRelation( "user", @@ -286,7 +286,7 @@ void testGetGraph() { @Test void setObjectTest() { // Arrange - Object object = Factory.buildObject("test_type", "test_id"); + Object object = Directory.buildObject("test_type", "test_id"); // Act SetObjectResponse setObjectResponse = directoryClient.setObject("test_type", "test_id"); @@ -314,7 +314,7 @@ void deleteObjectTest() { @Test void setRelationTest() { // Arrange - Relation relation = Factory.buildRelation("user", "morty@the-citadel.com", "friend", "user", "rick@the-citadel.com"); + Relation relation = Directory.buildRelation("user", "morty@the-citadel.com", "friend", "user", "rick@the-citadel.com"); // Act SetRelationResponse setRelationResponse = directoryClient.setRelation( @@ -420,13 +420,13 @@ void exportDataTest() { private List importCitadelDataList() { List importElements = new ArrayList<>(); - Object rick = Factory.buildObject("user", "rick@the-citadel.com"); - Object morty = Factory.buildObject("user", "morty@the-citadel.com"); - Object adminGroup = Factory.buildObject("group", "admin"); - Object editorGroup = Factory.buildObject("group", "editor"); - Relation rickAdminRelation = Factory.buildRelation("group", "admin", "member", "user", "rick@the-citadel.com"); - Relation mortyEditorRelation = Factory.buildRelation("group", "editor", "member", "user", "morty@the-citadel.com"); - Relation managerRelation = Factory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); + Object rick = Directory.buildObject("user", "rick@the-citadel.com"); + Object morty = Directory.buildObject("user", "morty@the-citadel.com"); + Object adminGroup = Directory.buildObject("group", "admin"); + Object editorGroup = Directory.buildObject("group", "editor"); + Relation rickAdminRelation = Directory.buildRelation("group", "admin", "member", "user", "rick@the-citadel.com"); + Relation mortyEditorRelation = Directory.buildRelation("group", "editor", "member", "user", "morty@the-citadel.com"); + Relation managerRelation = Directory.buildRelation("user", "morty@the-citadel.com", "manager", "user", "rick@the-citadel.com"); importElements.add(new ImportElement(rick)); importElements.add(new ImportElement(morty));