Skip to content

Commit

Permalink
filter feature on connector
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasCAI-mlv authored and loicgreffier committed Jul 31, 2024
1 parent 5670cf3 commit 8e6f00c
Show file tree
Hide file tree
Showing 6 changed files with 386 additions and 320 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ public class ConnectorController extends NamespacedResourceController {
ResourceQuotaService resourceQuotaService;

/**
* List connectors by namespace.
* List connectors by namespace, filtered by name parameter.
*
* @param namespace The namespace
* @param name The name parameter
* @return A list of connectors
*/
@Get
public List<Connector> list(String namespace) {
return connectorService.findAllForNamespace(getNamespace(namespace));
public List<Connector> list(String namespace, @QueryValue(defaultValue = "*") String name) {
return connectorService.findAllForNamespace(getNamespace(namespace), name);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,4 +374,4 @@ public boolean isAnyAclOfResource(List<AccessControlEntry> acls, String resource
case LITERAL -> resourceName.equals(acl.getSpec().getResource());
});
}
}
}
37 changes: 22 additions & 15 deletions src/main/java/com/michelin/ns4kafka/service/ConnectorService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.michelin.ns4kafka.service.client.connect.entities.ConnectorSpecs;
import com.michelin.ns4kafka.service.executor.ConnectorAsyncExecutor;
import com.michelin.ns4kafka.util.FormatErrorUtils;
import com.michelin.ns4kafka.util.RegexUtils;
import io.micronaut.context.ApplicationContext;
import io.micronaut.core.util.StringUtils;
import io.micronaut.http.HttpResponse;
Expand Down Expand Up @@ -57,23 +58,29 @@ public class ConnectorService {
* @return A list of connectors
*/
public List<Connector> findAllForNamespace(Namespace namespace) {
List<AccessControlEntry> acls = aclService.findAllGrantedToNamespace(namespace);
List<AccessControlEntry> acls = aclService
.findResourceOwnerGrantedToNamespace(namespace, AccessControlEntry.ResourceType.CONNECT);
return connectorRepository.findAllForCluster(namespace.getMetadata().getCluster())
.stream()
.filter(connector -> acls.stream().anyMatch(accessControlEntry -> {
if (accessControlEntry.getSpec().getPermission() != AccessControlEntry.Permission.OWNER) {
return false;
}
if (accessControlEntry.getSpec().getResourceType() == AccessControlEntry.ResourceType.CONNECT) {
return switch (accessControlEntry.getSpec().getResourcePatternType()) {
case PREFIXED -> connector.getMetadata().getName()
.startsWith(accessControlEntry.getSpec().getResource());
case LITERAL ->
connector.getMetadata().getName().equals(accessControlEntry.getSpec().getResource());
};
}
return false;
}))
.filter(connector -> aclService.isAnyAclOfResource(acls, connector.getMetadata().getName()))
.toList();
}

/**
* Find all connectors by given namespace, filtered by name parameter.
*
* @param namespace The namespace
* @param name The name filter
* @return A list of connectors
*/
public List<Connector> findAllForNamespace(Namespace namespace, String name) {
List<AccessControlEntry> acls = aclService
.findResourceOwnerGrantedToNamespace(namespace, AccessControlEntry.ResourceType.CONNECT);
List<String> nameFilterPatterns = RegexUtils.wildcardStringsToRegexPatterns(List.of(name));
return connectorRepository.findAllForCluster(namespace.getMetadata().getCluster())
.stream()
.filter(connector -> aclService.isAnyAclOfResource(acls, connector.getMetadata().getName())
&& RegexUtils.filterByPattern(connector.getMetadata().getName(), nameFilterPatterns))
.toList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,10 @@ void listEmptyConnectors() {
.build())
.build();

when(namespaceService.findByName("test"))
.thenReturn(Optional.of(ns));
when(connectorService.findAllForNamespace(ns))
.thenReturn(List.of());
when(namespaceService.findByName("test")).thenReturn(Optional.of(ns));
when(connectorService.findAllForNamespace(ns, "*")).thenReturn(List.of());

List<Connector> actual = connectorController.list("test");
assertTrue(actual.isEmpty());
assertTrue(connectorController.list("test", "*").isEmpty());
}

@Test
Expand All @@ -86,15 +83,30 @@ void listMultipleConnectors() {
.build())
.build();

when(namespaceService.findByName("test"))
.thenReturn(Optional.of(ns));
when(connectorService.findAllForNamespace(ns))
.thenReturn(List.of(
Connector.builder().metadata(Metadata.builder().name("connect1").build()).build(),
Connector.builder().metadata(Metadata.builder().name("connect2").build()).build()));
Connector connector1 = Connector.builder().metadata(Metadata.builder().name("connect1").build()).build();
Connector connector2 = Connector.builder().metadata(Metadata.builder().name("connect2").build()).build();

when(namespaceService.findByName("test")).thenReturn(Optional.of(ns));
when(connectorService.findAllForNamespace(ns, "*")).thenReturn(List.of(connector1, connector2));

assertEquals(List.of(connector1, connector2), connectorController.list("test", "*"));
}

@Test
void listConnectorWithNameParameter() {
Namespace ns = Namespace.builder()
.metadata(Metadata.builder()
.name("test")
.cluster("local")
.build())
.build();

Connector connector = Connector.builder().metadata(Metadata.builder().name("connect1").build()).build();

when(namespaceService.findByName("test")).thenReturn(Optional.of(ns));
when(connectorService.findAllForNamespace(ns, "connect1")).thenReturn(List.of(connector));

List<Connector> actual = connectorController.list("test");
assertEquals(2, actual.size());
assertEquals(List.of(connector), connectorController.list("test", "connect1"));
}

@Test
Expand Down
32 changes: 16 additions & 16 deletions src/test/java/com/michelin/ns4kafka/service/AclServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1017,24 +1017,24 @@ void isPrefixedAclOfResource() {
@Test
void isLiteralAclOfResource() {
AccessControlEntry acl1 = AccessControlEntry.builder()
.spec(AccessControlEntry.AccessControlEntrySpec.builder()
.resourceType(AccessControlEntry.ResourceType.TOPIC)
.resourcePatternType(AccessControlEntry.ResourcePatternType.LITERAL)
.permission(AccessControlEntry.Permission.OWNER)
.resource("abc.topic1")
.grantedTo("namespace")
.build())
.build();
.spec(AccessControlEntry.AccessControlEntrySpec.builder()
.resourceType(AccessControlEntry.ResourceType.TOPIC)
.resourcePatternType(AccessControlEntry.ResourcePatternType.LITERAL)
.permission(AccessControlEntry.Permission.OWNER)
.resource("abc.topic1")
.grantedTo("namespace")
.build())
.build();

AccessControlEntry acl2 = AccessControlEntry.builder()
.spec(AccessControlEntry.AccessControlEntrySpec.builder()
.resourceType(AccessControlEntry.ResourceType.CONNECT)
.resourcePatternType(AccessControlEntry.ResourcePatternType.LITERAL)
.permission(AccessControlEntry.Permission.OWNER)
.resource("abc-topic1")
.grantedTo("namespace")
.build())
.build();
.spec(AccessControlEntry.AccessControlEntrySpec.builder()
.resourceType(AccessControlEntry.ResourceType.CONNECT)
.resourcePatternType(AccessControlEntry.ResourcePatternType.LITERAL)
.permission(AccessControlEntry.Permission.OWNER)
.resource("abc-topic1")
.grantedTo("namespace")
.build())
.build();
List<AccessControlEntry> acls = List.of(acl1, acl2);

assertFalse(aclService.isAnyAclOfResource(acls, "xyz.topic1"));
Expand Down
Loading

0 comments on commit 8e6f00c

Please sign in to comment.