Skip to content

Commit 3a06d3a

Browse files
committed
Basic insert and search work with this commit, much work remains to be done
1 parent 7672bfc commit 3a06d3a

File tree

10 files changed

+330
-42
lines changed

10 files changed

+330
-42
lines changed

lightblue-ldap-common/src/main/java/com/redhat/lightblue/common/ldap/LdapDataStore.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public class LdapDataStore implements DataStore {
2727
public static final String BACKEND = "ldap";
2828

2929
private String database;
30+
private String baseDN;
31+
private String uniqueField;
3032

3133
public String getBackend() {
3234
return BACKEND;
@@ -40,6 +42,22 @@ public void setDatabase(String database) {
4042
this.database = database;
4143
}
4244

45+
public String getBaseDN() {
46+
return baseDN;
47+
}
48+
49+
public void setBaseDN(String baseDN) {
50+
this.baseDN = baseDN;
51+
}
52+
53+
public String getUniqueField() {
54+
return uniqueField;
55+
}
56+
57+
public void setUniqueField(String uniqueField) {
58+
this.uniqueField = uniqueField;
59+
}
60+
4361
public LdapDataStore(){}
4462

4563
public LdapDataStore(String database){
@@ -50,8 +68,11 @@ public LdapDataStore(String database){
5068
public int hashCode() {
5169
final int prime = 31;
5270
int result = 1;
71+
result = prime * result + ((baseDN == null) ? 0 : baseDN.hashCode());
5372
result = prime * result
5473
+ ((database == null) ? 0 : database.hashCode());
74+
result = prime * result
75+
+ ((uniqueField == null) ? 0 : uniqueField.hashCode());
5576
return result;
5677
}
5778

@@ -67,6 +88,14 @@ public boolean equals(Object obj) {
6788
return false;
6889
}
6990
LdapDataStore other = (LdapDataStore) obj;
91+
if (baseDN == null) {
92+
if (other.baseDN != null) {
93+
return false;
94+
}
95+
}
96+
else if (!baseDN.equals(other.baseDN)) {
97+
return false;
98+
}
7099
if (database == null) {
71100
if (other.database != null) {
72101
return false;
@@ -75,12 +104,21 @@ public boolean equals(Object obj) {
75104
else if (!database.equals(other.database)) {
76105
return false;
77106
}
107+
if (uniqueField == null) {
108+
if (other.uniqueField != null) {
109+
return false;
110+
}
111+
}
112+
else if (!uniqueField.equals(other.uniqueField)) {
113+
return false;
114+
}
78115
return true;
79116
}
80117

81118
@Override
82119
public String toString() {
83-
return "LdapDataStore [database=" + database + "]";
120+
return "LdapDataStore [database=" + database + ", baseDN=" + baseDN
121+
+ ", uniqueField=" + uniqueField + "]";
84122
}
85123

86124
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.redhat.lightblue.crud.ldap;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import com.redhat.lightblue.query.ArrayContainsExpression;
7+
import com.redhat.lightblue.query.ArrayMatchExpression;
8+
import com.redhat.lightblue.query.FieldComparisonExpression;
9+
import com.redhat.lightblue.query.NaryLogicalExpression;
10+
import com.redhat.lightblue.query.NaryRelationalExpression;
11+
import com.redhat.lightblue.query.QueryExpression;
12+
import com.redhat.lightblue.query.RegexMatchExpression;
13+
import com.redhat.lightblue.query.UnaryLogicalExpression;
14+
import com.redhat.lightblue.query.ValueComparisonExpression;
15+
import com.unboundid.ldap.sdk.Filter;
16+
17+
public class FilterTranslator {
18+
19+
public Filter translate(QueryExpression query){
20+
Filter filter;
21+
if (query instanceof ArrayContainsExpression) {
22+
filter = translate((ArrayContainsExpression) query);
23+
}
24+
else if (query instanceof ArrayMatchExpression) {
25+
filter = translate((ArrayMatchExpression) query);
26+
}
27+
else if (query instanceof FieldComparisonExpression) {
28+
filter = translate((FieldComparisonExpression) query);
29+
}
30+
else if (query instanceof NaryLogicalExpression) {
31+
filter = translate((NaryLogicalExpression) query);
32+
}
33+
else if (query instanceof NaryRelationalExpression) {
34+
filter = translate((NaryRelationalExpression) query);
35+
}
36+
else if (query instanceof RegexMatchExpression) {
37+
filter = translate((RegexMatchExpression) query);
38+
}
39+
else if (query instanceof UnaryLogicalExpression) {
40+
filter = translate((UnaryLogicalExpression) query);
41+
}
42+
else if (query instanceof ValueComparisonExpression){
43+
filter = translate((ValueComparisonExpression) query);
44+
}
45+
else{
46+
throw new IllegalArgumentException("Unsupported QueryExpression type: " + query.getClass());
47+
}
48+
return filter;
49+
}
50+
51+
private Filter translate(ArrayContainsExpression query){
52+
return null;
53+
}
54+
55+
private Filter translate(ArrayMatchExpression query){
56+
return null;
57+
}
58+
59+
private Filter translate(FieldComparisonExpression query){
60+
String field = query.getField().toString();
61+
String rfield = query.getRfield().toString();
62+
63+
switch(query.getOp()){
64+
case _eq:
65+
return Filter.createEqualityFilter(field, rfield);
66+
case _neq:
67+
return Filter.createNOTFilter(Filter.createEqualityFilter(field, rfield));
68+
case _gte:
69+
return Filter.createGreaterOrEqualFilter(field, rfield);
70+
case _lte:
71+
return Filter.createLessOrEqualFilter(field, rfield);
72+
default: //TODO gt, lt
73+
throw new IllegalArgumentException("Unsupported operation: " + query.getOp());
74+
}
75+
}
76+
77+
private Filter translate(NaryLogicalExpression query){
78+
List<Filter> filters = new ArrayList<Filter>();
79+
for(QueryExpression subQuery : query.getQueries()){
80+
translate(subQuery);
81+
}
82+
switch (query.getOp()){
83+
case _and:
84+
return Filter.createANDFilter(filters);
85+
case _or:
86+
return Filter.createORFilter(filters);
87+
default:
88+
throw new IllegalArgumentException("Unsupported operation: " + query.getOp());
89+
}
90+
}
91+
92+
private Filter translate(NaryRelationalExpression query){
93+
return null;
94+
}
95+
96+
private Filter translate(RegexMatchExpression query){
97+
return null;
98+
}
99+
100+
private Filter translate(UnaryLogicalExpression query){
101+
return null;
102+
}
103+
104+
private Filter translate(ValueComparisonExpression query){
105+
switch(query.getOp()){
106+
case _eq:
107+
return Filter.createEqualityFilter(query.getField().toString(), query.getRvalue().toString());
108+
default:
109+
throw new IllegalArgumentException("Unsupported operation: " + query.getOp());
110+
}
111+
}
112+
113+
}

lightblue-ldap-crud/src/main/java/com/redhat/lightblue/crud/ldap/LdapCRUDController.java

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,9 @@
2323
import java.util.List;
2424
import java.util.Map;
2525

26-
import org.slf4j.Logger;
27-
import org.slf4j.LoggerFactory;
28-
2926
import com.fasterxml.jackson.databind.JsonNode;
3027
import com.redhat.lightblue.common.ldap.DBResolver;
28+
import com.redhat.lightblue.common.ldap.LdapDataStore;
3129
import com.redhat.lightblue.crud.CRUDController;
3230
import com.redhat.lightblue.crud.CRUDDeleteResponse;
3331
import com.redhat.lightblue.crud.CRUDFindResponse;
@@ -36,7 +34,10 @@
3634
import com.redhat.lightblue.crud.CRUDSaveResponse;
3735
import com.redhat.lightblue.crud.CRUDUpdateResponse;
3836
import com.redhat.lightblue.crud.DocCtx;
37+
import com.redhat.lightblue.eval.FieldAccessRoleEvaluator;
38+
import com.redhat.lightblue.eval.Projector;
3939
import com.redhat.lightblue.hystrix.ldap.InsertCommand;
40+
import com.redhat.lightblue.metadata.DataStore;
4041
import com.redhat.lightblue.metadata.EntityMetadata;
4142
import com.redhat.lightblue.metadata.MetadataListener;
4243
import com.redhat.lightblue.query.Projection;
@@ -46,17 +47,18 @@
4647
import com.redhat.lightblue.util.JsonDoc;
4748
import com.unboundid.ldap.sdk.Attribute;
4849
import com.unboundid.ldap.sdk.Entry;
50+
import com.unboundid.ldap.sdk.Filter;
4951
import com.unboundid.ldap.sdk.LDAPConnection;
5052
import com.unboundid.ldap.sdk.LDAPException;
5153
import com.unboundid.ldap.sdk.LDAPResult;
5254
import com.unboundid.ldap.sdk.ResultCode;
55+
import com.unboundid.ldap.sdk.SearchRequest;
56+
import com.unboundid.ldap.sdk.SearchResult;
57+
import com.unboundid.ldap.sdk.SearchResultEntry;
58+
import com.unboundid.ldap.sdk.SearchScope;
5359

5460
public class LdapCRUDController implements CRUDController{
5561

56-
private static final Logger LOGGER = LoggerFactory.getLogger(LdapCRUDController.class);
57-
58-
private static final String DN = "dn";
59-
6062
private final DBResolver dbResolver;
6163

6264
public LdapCRUDController(DBResolver dbResolver){
@@ -74,6 +76,7 @@ public CRUDInsertionResponse insert(CRUDOperationContext ctx,
7476
}
7577

7678
EntityMetadata md = ctx.getEntityMetadata(ctx.getEntityName());
79+
LdapDataStore store = getLdapDataStore(md);
7780

7881
//TODO Revisit Projection
7982
//FieldAccessRoleEvaluator roleEval = new FieldAccessRoleEvaluator(md, ctx.getCallerRoles());
@@ -87,23 +90,26 @@ public CRUDInsertionResponse insert(CRUDOperationContext ctx,
8790
}*/
8891

8992
try {
90-
LDAPConnection connection = dbResolver.get(md.getDataStore());
93+
LDAPConnection connection = dbResolver.get(store);
9194

9295
for(DocCtx document : documents){
9396
//document.setOriginalDocument(document);
9497
JsonNode rootNode = document.getRoot();
95-
JsonNode dnNode = rootNode.get(DN);
96-
if(dnNode == null){
97-
throw new IllegalArgumentException("dn is a required field");
98+
99+
JsonNode uniqueNode = rootNode.get(store.getUniqueField());
100+
if(uniqueNode == null){
101+
throw new IllegalArgumentException(store.getUniqueField() + " is a required field");
98102
}
99103

100-
Entry entry = new Entry(dnNode.asText());
104+
Entry entry = new Entry(createDN(store, uniqueNode.asText()));
101105

102106
Iterator<Map.Entry<String, JsonNode>> nodeIterator = rootNode.fields();
103107
while(nodeIterator.hasNext()){
104108
Map.Entry<String, JsonNode> node = nodeIterator.next();
105-
if(DN.equalsIgnoreCase(node.getKey())){
106-
continue;
109+
if("dn".equalsIgnoreCase(node.getKey())){
110+
throw new IllegalArgumentException(
111+
"DN should not be included as it's value will be derived from the metadata.basedn and" +
112+
" the metadata.uniqueattr. Including the DN as an insert attribute is confusing.");
107113
}
108114

109115
JsonNode valueNode = node.getValue();
@@ -168,8 +174,50 @@ public CRUDDeleteResponse delete(CRUDOperationContext ctx,
168174
public CRUDFindResponse find(CRUDOperationContext ctx,
169175
QueryExpression query, Projection projection, Sort sort, Long from,
170176
Long to) {
171-
// TODO Auto-generated method stub
172-
return null;
177+
178+
if (query == null) {
179+
throw new IllegalArgumentException("No query was provided.");
180+
}
181+
if (projection == null) {
182+
throw new IllegalArgumentException("No projection was provided");
183+
}
184+
185+
EntityMetadata md = ctx.getEntityMetadata(ctx.getEntityName());
186+
LdapDataStore store = getLdapDataStore(md);
187+
188+
CRUDFindResponse response = new CRUDFindResponse();
189+
response.setSize(0);
190+
191+
try {
192+
LDAPConnection connection = dbResolver.get(store);
193+
194+
Filter filter = new FilterTranslator().translate(query);
195+
SearchRequest request = new SearchRequest(store.getBaseDN(), SearchScope.SUB, filter, "*");
196+
SearchResult result = connection.search(request);
197+
198+
response.setSize(result.getEntryCount());
199+
for(SearchResultEntry resultEntry : result.getSearchEntries()){
200+
resultEntry.getDN();
201+
}
202+
203+
Projector projector = Projector.getInstance(
204+
Projection.add(
205+
projection,
206+
new FieldAccessRoleEvaluator(
207+
md,
208+
ctx.getCallerRoles()).getExcludedFields(FieldAccessRoleEvaluator.Operation.find)
209+
),
210+
md);
211+
for (DocCtx document : ctx.getDocuments()) {
212+
document.setOutputDocument(projector.project(document, ctx.getFactory().getNodeFactory()));
213+
}
214+
}
215+
catch (LDAPException e) {
216+
// TODO Auto-generated catch block
217+
e.printStackTrace();
218+
}
219+
220+
return response;
173221
}
174222

175223
public void updatePredefinedFields(CRUDOperationContext ctx, JsonDoc doc) {
@@ -180,4 +228,16 @@ public MetadataListener getMetadataListener() {
180228
return null;
181229
}
182230

231+
private LdapDataStore getLdapDataStore(EntityMetadata md){
232+
DataStore store = md.getDataStore();
233+
if(!(store instanceof LdapDataStore)){
234+
throw new IllegalArgumentException("DataStore of type " + store.getClass() + " is not supported.");
235+
}
236+
return (LdapDataStore) store;
237+
}
238+
239+
private String createDN(LdapDataStore store, String uniqueValue){
240+
return store.getUniqueField() + "=" + uniqueValue + "," + store.getBaseDN();
241+
}
242+
183243
}

0 commit comments

Comments
 (0)