-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add namespace filter option in config file #2688
Changes from 6 commits
2d7e24e
c7c3607
4d8b91d
5da8b07
09f0418
6294c8e
4a6c80c
beab297
c5e445a
bec782e
ea55703
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package marquez.api.filter.exclusions; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import lombok.Getter; | ||
|
||
public class ExclusionsConfig { | ||
@Getter @JsonProperty public NamespaceExclusion namespaces; | ||
|
||
public static class NamespaceExclusion { | ||
@Getter @JsonProperty public boolean onRead; | ||
@Getter @JsonProperty public boolean onWrite; | ||
@Getter @JsonProperty public String patterns; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a single pattern or a list of patterns separated in some way? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @pawel-big-lebowski yes, sorry about that, I forgot to include the proper documentation. I added a section to the FAQ to explain the usage, I'd be happy to move it to another place that is more suitable if needed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have 2 options:
I think option
while option
I think either option works and perhaps we just rename |
||
} | ||
; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package marquez.api.filter.exclusions; | ||
|
||
public class ExclusionsFilter { | ||
private static String namespacesFilter; | ||
|
||
public static void setNamespacesReadFilter(String filter) { | ||
namespacesFilter = filter; | ||
} | ||
|
||
public static String getNamespacesReadFilter() { | ||
return namespacesFilter; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package marquez.api; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertFalse; | ||
import static org.mockito.ArgumentMatchers.anyInt; | ||
import static org.mockito.ArgumentMatchers.eq; | ||
import static org.mockito.Mockito.doCallRealMethod; | ||
import static org.mockito.Mockito.spy; | ||
import static org.mockito.Mockito.when; | ||
|
||
import java.util.List; | ||
import javax.ws.rs.core.Response; | ||
import marquez.api.NamespaceResource.Namespaces; | ||
import marquez.api.filter.exclusions.ExclusionsFilter; | ||
import marquez.common.models.NamespaceName; | ||
import marquez.common.models.OwnerName; | ||
import marquez.db.BaseDao; | ||
import marquez.db.NamespaceDao; | ||
import marquez.jdbi.MarquezJdbiExternalPostgresExtension; | ||
import marquez.service.NamespaceService; | ||
import marquez.service.ServiceFactory; | ||
import marquez.service.models.Namespace; | ||
import marquez.service.models.NamespaceMeta; | ||
import org.jdbi.v3.core.Jdbi; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.Mock; | ||
import org.mockito.MockitoAnnotations; | ||
|
||
@ExtendWith(MarquezJdbiExternalPostgresExtension.class) | ||
public class NamespaceResourceTest { | ||
|
||
@Mock private ServiceFactory serviceFactory; | ||
|
||
@Mock private BaseDao baseDao; | ||
|
||
private static NamespaceDao namespaceDao; | ||
private NamespaceService namespaceService; | ||
private NamespaceResource namespaceResource; | ||
|
||
@BeforeEach | ||
public void setUp(Jdbi jdbi) { | ||
MockitoAnnotations.openMocks(this); | ||
|
||
namespaceDao = jdbi.onDemand(NamespaceDao.class); | ||
when(baseDao.createNamespaceDao()).thenReturn(namespaceDao); | ||
namespaceService = new NamespaceService(baseDao); | ||
|
||
when(serviceFactory.getNamespaceService()).thenReturn(namespaceService); | ||
namespaceResource = new NamespaceResource(serviceFactory); | ||
} | ||
|
||
@Test | ||
void testFindAllFilter() { | ||
var namespaceName1 = NamespaceName.of("postgres://localhost:5432"); | ||
var namespaceMeta1 = new NamespaceMeta(new OwnerName("marquez"), null); | ||
namespaceDao.upsertNamespaceMeta(namespaceName1, namespaceMeta1); | ||
|
||
var namespaceName2 = NamespaceName.of("excluded_namespace"); | ||
var namespaceMeta2 = new NamespaceMeta(new OwnerName("yannick"), null); | ||
namespaceDao.upsertNamespaceMeta(namespaceName2, namespaceMeta2); | ||
|
||
List<Namespace> namespaces = namespaceDao.findAllFilter("excluded.*", 10, 0); | ||
|
||
// Assert that the namespaces list does not contain the excluded namespace | ||
assertFalse( | ||
namespaces.stream().anyMatch(namespace -> namespace.getName().equals(namespaceName2))); | ||
} | ||
|
||
@Test | ||
public void testListWithFilter() { | ||
String filter = "excluded_.*"; | ||
ExclusionsFilter.setNamespacesReadFilter(filter); | ||
|
||
NamespaceName namespaceName = NamespaceName.of("excluded_namespace"); | ||
OwnerName owner = new OwnerName("yannick"); | ||
NamespaceMeta namespaceMeta = new NamespaceMeta(owner, "description"); | ||
|
||
namespaceDao.upsertNamespaceMeta(namespaceName, namespaceMeta); | ||
|
||
NamespaceService namespaceServiceSpy = spy(namespaceService); | ||
doCallRealMethod().when(namespaceServiceSpy).findAllFilter(eq(filter), anyInt(), anyInt()); | ||
|
||
Response response = namespaceResource.list(10, 0); | ||
Namespaces namespaces = (Namespaces) response.getEntity(); | ||
|
||
// Check if the returned namespaces contain a namespace with the name | ||
// "excluded_namespace" | ||
boolean containsExcludedNamespace = | ||
namespaces.getValue().stream() | ||
.anyMatch(namespace -> namespace.getName().getValue().equals("excluded_namespace")); | ||
|
||
// Assert that the returned namespaces do not contain a namespace with the name | ||
// "excluded_namespace" | ||
assertFalse(containsExcludedNamespace); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package marquez.api.filter.exclusions; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
|
||
import marquez.api.filter.exclusions.ExclusionsConfig.NamespaceExclusion; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
|
||
class ExclusionsConfigTest { | ||
|
||
private ExclusionsConfig exclusionsConfig; | ||
private NamespaceExclusion namespaceExclusion; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
exclusionsConfig = new ExclusionsConfig(); | ||
namespaceExclusion = new NamespaceExclusion(); | ||
} | ||
|
||
@Test | ||
void testNamespaceExclusionOnRead() { | ||
namespaceExclusion.onRead = true; | ||
assertEquals(true, namespaceExclusion.isOnRead()); | ||
} | ||
|
||
@Test | ||
void testNamespaceExclusionOnWrite() { | ||
namespaceExclusion.onWrite = true; | ||
assertEquals(true, namespaceExclusion.isOnWrite()); | ||
} | ||
|
||
@Test | ||
void testNamespaceExclusionPatterns() { | ||
String patterns = "test-pattern"; | ||
namespaceExclusion.patterns = patterns; | ||
assertEquals(patterns, namespaceExclusion.getPatterns()); | ||
} | ||
|
||
@Test | ||
void testExclusionsConfigNamespaces() { | ||
exclusionsConfig.namespaces = namespaceExclusion; | ||
assertNotNull(exclusionsConfig.getNamespaces()); | ||
assertEquals(namespaceExclusion, exclusionsConfig.getNamespaces()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package marquez.api.filter.exclusions; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
|
||
public class ExclusionsFilterTest { | ||
|
||
private static final String TEST_FILTER = "test-filter"; | ||
|
||
@BeforeEach | ||
public void setUp() { | ||
ExclusionsFilter.setNamespacesReadFilter(null); | ||
} | ||
|
||
@Test | ||
public void testSetAndGetNamespacesReadFilter() { | ||
ExclusionsFilter.setNamespacesReadFilter(TEST_FILTER); | ||
String result = ExclusionsFilter.getNamespacesReadFilter(); | ||
assertEquals(TEST_FILTER, result); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! To clean up the code, I suggest (FYI, these are only suggestions and feel free to modify as needed):
Exclusions
with a cleaner interface defined in pkgmarquez.exclusions
, ormarquez.common
(see below) in place ofExclusionsFilter
NamespaceService.findAll()
orNamespaceService.findAllWith()
Exclusions.java
Then, you can chain your calls:
NamespaceResource.list()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yanlibert I'm wondering, as we work through the
Exclusions
code, would it make sense to just have:where
onRead
andonWrite
can be different (or equal). This would give greater control and flexibility over what to exclude 😅There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a great suggestion, I refactored the code accordingly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wslulciuc I also think option 2 where
pattern
is a string of regex is simpler, and more straightforward to implement as I'm not a java dev 😄I increased the coverage and refactored the code as suggested by implementing a cleaner Exclusions interface.