killbill-memoizeit

Merge branch 'work-for-release-0.21.x' of github.com:killbill/killbill

3/5/2019 6:51:54 PM

Details

diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
index ad85ec7..6447a94 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
@@ -22,6 +22,7 @@ import java.net.URI;
 import java.util.List;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
@@ -55,6 +56,8 @@ import org.killbill.clock.Clock;
 import org.killbill.commons.metrics.TimedResource;
 
 import com.google.common.base.Function;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -109,6 +112,47 @@ public class CustomFieldResource extends JaxRsResourceBase {
                                                 nextPageUri);
     }
 
+
+    @TimedResource
+    @GET
+    @Path("/" + SEARCH )
+    @Produces(APPLICATION_JSON)
+    @ApiOperation(value = "Search custom fields by type, name and optional value", response = CustomFieldJson.class, responseContainer = "List")
+    @ApiResponses(value = {})
+    public Response searchCustomFieldsByTypeName(@QueryParam("objectType") final String objectType,
+                                                 @QueryParam("fieldName") final String fieldName,
+                                                 @Nullable @QueryParam("fieldValue") final String fieldValue,
+                                                 @QueryParam(QUERY_SEARCH_OFFSET) @DefaultValue("0") final Long offset,
+                                                 @QueryParam(QUERY_SEARCH_LIMIT) @DefaultValue("100") final Long limit,
+                                                 @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
+                                                 @javax.ws.rs.core.Context final HttpServletRequest request) {
+
+        Preconditions.checkNotNull(objectType);
+        Preconditions.checkNotNull(fieldName);
+
+        final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
+        final Pagination<CustomField> customFields = fieldValue != null ?
+                                                     customFieldUserApi.searchCustomFields(fieldName, fieldValue, ObjectType.valueOf(objectType), offset, limit, tenantContext) :
+                                                     customFieldUserApi.searchCustomFields(fieldName,  ObjectType.valueOf(objectType), offset, limit, tenantContext);
+
+        final URI nextPageUri = uriBuilder.nextPage(CustomFieldResource.class, "searchCustomFields", customFields.getNextOffset(), limit, ImmutableMap.<String, String>of("objectType", objectType,
+                                                                                                                                                                          "fieldName", fieldName,
+                                                                                                                                                                          "fieldValue", MoreObjects.firstNonNull(fieldValue, ""),
+                                                                                                                                                                          QUERY_AUDIT, auditMode.getLevel().toString()));
+        return buildStreamingPaginationResponse(customFields,
+                                                new Function<CustomField, CustomFieldJson>() {
+                                                    @Override
+                                                    public CustomFieldJson apply(final CustomField customField) {
+                                                        // TODO Really slow - we should instead try to figure out the account id
+                                                        final List<AuditLog> auditLogs = auditUserApi.getAuditLogs(customField.getId(), ObjectType.CUSTOM_FIELD, auditMode.getLevel(), tenantContext);
+                                                        return new CustomFieldJson(customField, auditLogs);
+                                                    }
+                                                },
+                                                nextPageUri);
+    }
+
+
+
     @TimedResource
     @GET
     @Path("/" + SEARCH + "/{searchKey:" + ANYTHING_PATTERN + "}")
@@ -136,6 +180,8 @@ public class CustomFieldResource extends JaxRsResourceBase {
                                                 nextPageUri);
     }
 
+
+
     @TimedResource
     @GET
     @Path("/{customFieldId:" + UUID_PATTERN + "}/" + AUDIT_LOG_WITH_HISTORY)

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index 1cebe3f..75d763c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.143.11</version>
+        <version>0.143.12</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.20.7-SNAPSHOT</version>
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCustomField.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCustomField.java
index 96cbb8b..d96d583 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCustomField.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCustomField.java
@@ -106,12 +106,30 @@ public class TestCustomField extends TestJaxrsBase {
             doSearchCustomField(customField.getValue(), customField);
         }
 
+        // Search by key
         final CustomFields customFields = customFieldApi.searchCustomFields(ObjectType.ACCOUNT.toString(), requestOptions);
         Assert.assertEquals(customFields.size(), 5);
         Assert.assertEquals(customFields.getPaginationCurrentOffset(), 0);
         Assert.assertEquals(customFields.getPaginationTotalNbRecords(), 5);
         Assert.assertEquals(customFields.getPaginationMaxNbRecords(), 5);
 
+
+        // Search by type, name
+        final CustomFields customFields2 = customFieldApi.searchCustomFieldsByTypeName(ObjectType.ACCOUNT.toString(), input.get(0).getName(), null, requestOptions);
+        Assert.assertEquals(customFields2.size(), 1);
+        Assert.assertEquals(customFields2.getPaginationCurrentOffset(), 0);
+        Assert.assertEquals(customFields2.getPaginationTotalNbRecords(), 1);
+        Assert.assertEquals(customFields2.getPaginationMaxNbRecords(), 5);
+
+
+        // Search by type, name, value
+        final CustomFields customFields3 = customFieldApi.searchCustomFieldsByTypeName(ObjectType.ACCOUNT.toString(), input.get(0).getName(),  input.get(0).getValue(), requestOptions);
+        Assert.assertEquals(customFields3.size(), 1);
+        Assert.assertEquals(customFields3.getPaginationCurrentOffset(), 0);
+        Assert.assertEquals(customFields3.getPaginationTotalNbRecords(), 1);
+        Assert.assertEquals(customFields3.getPaginationMaxNbRecords(), 5);
+
+
         final CustomFields allAccountCustomFields = accountApi.getAllCustomFields(account.getAccountId(), null, AuditLevel.FULL, requestOptions);
         Assert.assertEquals(allAccountCustomFields.size(), 5);
 
diff --git a/util/src/main/java/org/killbill/billing/util/customfield/api/DefaultCustomFieldUserApi.java b/util/src/main/java/org/killbill/billing/util/customfield/api/DefaultCustomFieldUserApi.java
index 0a48837..af7b0df 100644
--- a/util/src/main/java/org/killbill/billing/util/customfield/api/DefaultCustomFieldUserApi.java
+++ b/util/src/main/java/org/killbill/billing/util/customfield/api/DefaultCustomFieldUserApi.java
@@ -76,6 +76,32 @@ public class DefaultCustomFieldUserApi implements CustomFieldUserApi {
     }
 
     @Override
+    public Pagination<CustomField> searchCustomFields(final String fieldName, final String fieldValue, final ObjectType objectType, final Long offset, final Long limit, final TenantContext context) {
+        return getEntityPaginationNoException(limit,
+                                              new SourcePaginationBuilder<CustomFieldModelDao, CustomFieldApiException>() {
+                                                  @Override
+                                                  public Pagination<CustomFieldModelDao> build() {
+                                                      return customFieldDao.searchCustomFields(fieldName, fieldValue, objectType, offset, limit, internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(context));
+                                                  }
+                                              },
+                                              CUSTOM_FIELD_MODEL_DAO_CUSTOM_FIELD_FUNCTION);
+    }
+
+
+    @Override
+    public Pagination<CustomField> searchCustomFields(final String fieldName, final ObjectType objectType, final Long offset, final Long limit, final TenantContext context) {
+        return getEntityPaginationNoException(limit,
+                                              new SourcePaginationBuilder<CustomFieldModelDao, CustomFieldApiException>() {
+                                                  @Override
+                                                  public Pagination<CustomFieldModelDao> build() {
+                                                      return customFieldDao.searchCustomFields(fieldName, objectType, offset, limit, internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(context));
+                                                  }
+                                              },
+                                              CUSTOM_FIELD_MODEL_DAO_CUSTOM_FIELD_FUNCTION);
+    }
+
+
+    @Override
     public Pagination<CustomField> getCustomFields(final Long offset, final Long limit, final TenantContext context) {
         return getEntityPaginationNoException(limit,
                                               new SourcePaginationBuilder<CustomFieldModelDao, CustomFieldApiException>() {
diff --git a/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldDao.java b/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldDao.java
index 313643e..3f0b226 100644
--- a/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldDao.java
+++ b/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldDao.java
@@ -33,6 +33,10 @@ public interface CustomFieldDao extends EntityDao<CustomFieldModelDao, CustomFie
 
     public Pagination<CustomFieldModelDao> searchCustomFields(String searchKey, Long offset, Long limit, InternalTenantContext context);
 
+    public Pagination<CustomFieldModelDao> searchCustomFields(final String fieldName, final ObjectType objectType, Long offset, Long limit, InternalTenantContext context);
+
+    public Pagination<CustomFieldModelDao> searchCustomFields(final String fieldName, final String fieldValue, final ObjectType objectType, Long offset, Long limit, InternalTenantContext context);
+
     public List<CustomFieldModelDao> getCustomFieldsForObject(final UUID objectId, final ObjectType objectType, final InternalTenantContext context);
 
     public List<CustomFieldModelDao> getCustomFieldsForAccountType(final ObjectType objectType, final InternalTenantContext context);
diff --git a/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java b/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java
index e3d88b2..051c253 100644
--- a/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java
@@ -16,6 +16,7 @@
 
 package org.killbill.billing.util.customfield.dao;
 
+import java.util.Iterator;
 import java.util.List;
 import java.util.UUID;
 
@@ -27,10 +28,12 @@ import org.killbill.billing.util.customfield.CustomField;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
 import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.statement.SmartFetchSize;
 import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.Define;
 
 @KillBillSqlDaoStringTemplate
 public interface CustomFieldSqlDao extends EntitySqlDao<CustomFieldModelDao, CustomField> {
@@ -51,4 +54,37 @@ public interface CustomFieldSqlDao extends EntitySqlDao<CustomFieldModelDao, Cus
     List<CustomFieldModelDao> getCustomFieldsForObject(@Bind("objectId") UUID objectId,
                                                        @Bind("objectType") ObjectType objectType,
                                                        @SmartBindBean InternalTenantContext internalTenantContext);
+
+    @SqlQuery
+    @SmartFetchSize(shouldStream = true)
+    public Iterator<CustomFieldModelDao> searchByObjectTypeAndFieldName(@Bind("fieldName") String fieldName,
+                                                                        @Bind("objectType") ObjectType objectType,
+                                                                        @Bind("offset") final Long offset,
+                                                                        @Bind("rowCount") final Long rowCount,
+                                                                        @Define("ordering") final String ordering,
+                                                                        @SmartBindBean final InternalTenantContext context);
+
+    @SqlQuery
+    public Long getSearchCountByObjectTypeAndFieldName(@Bind("fieldName") String fieldName,
+                                                       @Bind("objectType") ObjectType objectType,
+                                                       @SmartBindBean final InternalTenantContext context);
+
+
+    @SqlQuery
+    @SmartFetchSize(shouldStream = true)
+    public Iterator<CustomFieldModelDao> searchByObjectTypeAndFieldNameValue(@Bind("fieldName") String fieldName,
+                                                                             @Bind("fieldValue") final String fieldValue,
+                                                                             @Bind("objectType") ObjectType objectType,
+                                                                             @Bind("offset") final Long offset,
+                                                                             @Bind("rowCount") final Long rowCount,
+                                                                             @Define("ordering") final String ordering,
+                                                                             @SmartBindBean final InternalTenantContext context);
+
+    @SqlQuery
+    public Long getSearchCountByObjectTypeAndFieldNameValue(@Bind("fieldName") String fieldName,
+                                                            @Bind("fieldValue") final String fieldValue,
+                                                            @Bind("objectType") ObjectType objectType,
+                                                            @SmartBindBean final InternalTenantContext context);
+
+
 }
diff --git a/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java b/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java
index 9582b1e..7ac724f 100644
--- a/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java
+++ b/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java
@@ -244,4 +244,44 @@ public class DefaultCustomFieldDao extends EntityDaoBase<CustomFieldModelDao, Cu
                                               limit,
                                               context);
     }
+
+    @Override
+    public Pagination<CustomFieldModelDao> searchCustomFields(final String fieldName, final ObjectType objectType, final Long offset, final Long limit, final InternalTenantContext context) {
+        return paginationHelper.getPagination(CustomFieldSqlDao.class,
+                                              new PaginationIteratorBuilder<CustomFieldModelDao, CustomField, CustomFieldSqlDao>() {
+                                                  @Override
+                                                  public Long getCount(final CustomFieldSqlDao customFieldSqlDao, final InternalTenantContext context) {
+                                                      return customFieldSqlDao.getSearchCountByObjectTypeAndFieldName(fieldName, objectType, context);
+                                                  }
+
+                                                  @Override
+                                                  public Iterator<CustomFieldModelDao> build(final CustomFieldSqlDao customFieldSqlDao, final Long offset, final Long limit, final Ordering ordering, final InternalTenantContext context) {
+                                                      return customFieldSqlDao.searchByObjectTypeAndFieldName(fieldName, objectType, offset, limit, ordering.toString(), context);
+                                                  }
+                                              },
+                                              offset,
+                                              limit,
+                                              context);
+    }
+
+    @Override
+    public Pagination<CustomFieldModelDao> searchCustomFields(final String fieldName, @Nullable final String fieldValue, final ObjectType objectType, final Long offset, final Long limit, final InternalTenantContext context) {
+        return paginationHelper.getPagination(CustomFieldSqlDao.class,
+                                              new PaginationIteratorBuilder<CustomFieldModelDao, CustomField, CustomFieldSqlDao>() {
+                                                  @Override
+                                                  public Long getCount(final CustomFieldSqlDao customFieldSqlDao, final InternalTenantContext context) {
+                                                      return customFieldSqlDao.getSearchCountByObjectTypeAndFieldNameValue(fieldName, fieldValue, objectType, context);
+                                                  }
+
+                                                  @Override
+                                                  public Iterator<CustomFieldModelDao> build(final CustomFieldSqlDao customFieldSqlDao, final Long offset, final Long limit, final Ordering ordering, final InternalTenantContext context) {
+                                                      return customFieldSqlDao.searchByObjectTypeAndFieldNameValue(fieldName, fieldValue, objectType, offset, limit, ordering.toString(), context);
+                                                  }
+                                              },
+                                              offset,
+                                              limit,
+                                              context);
+    }
+
+
 }
diff --git a/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
index b2af285..96a2ab0 100644
--- a/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
@@ -67,3 +67,60 @@ searchQuery(prefix) ::= <<
   or <prefix>field_name like :likeSearchKey
   or <prefix>field_value like :likeSearchKey
 >>
+
+getSearchCountByObjectTypeAndFieldName() ::= <<
+select
+count(1) as count
+from <tableName()>
+where
+object_type = :objectType
+and field_name = :fieldName
+<andCheckSoftDeletionWithComma("")>
+<AND_CHECK_TENANT("")>
+;
+>>
+
+searchByObjectTypeAndFieldName(ordering) ::= <<
+select
+<allTableFields()>
+from <tableName()>
+where
+object_type = :objectType
+and field_name = :fieldName
+<andCheckSoftDeletionWithComma("")>
+<AND_CHECK_TENANT("")>
+order by <recordIdField("")> <ordering>
+limit :rowCount offset :offset
+;
+>>
+
+getSearchCountByObjectTypeAndFieldNameValue() ::= <<
+select
+count(1) as count
+from <tableName()>
+where
+object_type = :objectType
+and field_name = :fieldName
+and field_value = :fieldValue
+<andCheckSoftDeletionWithComma("")>
+<AND_CHECK_TENANT("")>
+;
+>>
+
+searchByObjectTypeAndFieldNameValue(ordering) ::= <<
+select
+<allTableFields()>
+from <tableName()>
+where
+object_type = :objectType
+and field_name = :fieldName
+and field_value = :fieldValue
+<andCheckSoftDeletionWithComma("")>
+<AND_CHECK_TENANT("")>
+order by <recordIdField("")> <ordering>
+limit :rowCount offset :offset
+;
+>>
+
+
+
diff --git a/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java b/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java
index e3a782a..c4efd7e 100644
--- a/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java
+++ b/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java
@@ -73,4 +73,14 @@ public class MockCustomFieldDao extends MockEntityDaoBase<CustomFieldModelDao, C
     public Pagination<CustomFieldModelDao> searchCustomFields(final String searchKey, final Long offset, final Long limit, final InternalTenantContext context) {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public Pagination<CustomFieldModelDao> searchCustomFields(final String fieldName, final ObjectType objectType, final Long offset, final Long limit, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Pagination<CustomFieldModelDao> searchCustomFields(final String fieldName, final String fieldValue, final ObjectType objectType, final Long offset, final Long limit, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/util/src/test/java/org/killbill/billing/util/customfield/dao/TestDefaultCustomFieldDao.java b/util/src/test/java/org/killbill/billing/util/customfield/dao/TestDefaultCustomFieldDao.java
new file mode 100644
index 0000000..1efb1f9
--- /dev/null
+++ b/util/src/test/java/org/killbill/billing/util/customfield/dao/TestDefaultCustomFieldDao.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2014-2019 Groupon, Inc
+ * Copyright 2014-2019 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.util.customfield.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.killbill.billing.ObjectType;
+import org.killbill.billing.api.TestApiListener.NextEvent;
+import org.killbill.billing.util.UtilTestSuiteWithEmbeddedDB;
+import org.killbill.billing.util.api.CustomFieldApiException;
+import org.killbill.billing.util.entity.Pagination;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class TestDefaultCustomFieldDao extends UtilTestSuiteWithEmbeddedDB {
+
+    @Test(groups = "slow")
+    public void testSearchByObjectTypeAndFields() throws CustomFieldApiException {
+
+        final UUID someUUId = UUID.randomUUID();
+        final String SEARCHABLE_FILED_NAME = "ToBeSearched";
+        final String NON_SEARCHABLE_FILED_NAME = "NotToBeFound";
+
+        final List<CustomFieldModelDao> input = ImmutableList.of(
+                new CustomFieldModelDao(internalCallContext.getCreatedDate(), SEARCHABLE_FILED_NAME, "The world will collapse soon!", someUUId, ObjectType.ACCOUNT),
+                new CustomFieldModelDao(internalCallContext.getCreatedDate(), SEARCHABLE_FILED_NAME, "How do you know?", someUUId, ObjectType.ACCOUNT),
+                new CustomFieldModelDao(internalCallContext.getCreatedDate(), SEARCHABLE_FILED_NAME, "Just a guess...", someUUId, ObjectType.INVOICE),
+                new CustomFieldModelDao(internalCallContext.getCreatedDate(), NON_SEARCHABLE_FILED_NAME, "Are you a psychic???", someUUId, ObjectType.ACCOUNT),
+                new CustomFieldModelDao(internalCallContext.getCreatedDate(), NON_SEARCHABLE_FILED_NAME, "Yes!!!!", someUUId, ObjectType.INVOICE));
+
+        eventsListener.pushExpectedEvents(NextEvent.CUSTOM_FIELD, NextEvent.CUSTOM_FIELD, NextEvent.CUSTOM_FIELD, NextEvent.CUSTOM_FIELD, NextEvent.CUSTOM_FIELD);
+        ((DefaultCustomFieldDao) customFieldDao).create(input, internalCallContext);
+        eventsListener.assertListenerStatus();
+
+        Pagination<CustomFieldModelDao> result = customFieldDao.searchCustomFields(SEARCHABLE_FILED_NAME, ObjectType.INVOICE, 0L, 100L, internalCallContext);
+        Assert.assertEquals(result.getTotalNbRecords().longValue(), 1L);
+        Assert.assertEquals(result.getMaxNbRecords().longValue(), 5L);
+        CustomFieldModelDao nextCustomField = result.iterator().next();
+        Assert.assertEquals(nextCustomField.getObjectType(), ObjectType.INVOICE);
+        Assert.assertEquals(nextCustomField.getFieldName(), SEARCHABLE_FILED_NAME);
+
+
+        result = customFieldDao.searchCustomFields(SEARCHABLE_FILED_NAME, ObjectType.ACCOUNT, 0L, 100L, internalCallContext);
+        Assert.assertEquals(result.getTotalNbRecords().longValue(), 2L);
+        Assert.assertEquals(result.getMaxNbRecords().longValue(), 5L);
+
+        nextCustomField = result.iterator().next();
+        Assert.assertEquals(nextCustomField.getObjectType(), ObjectType.ACCOUNT);
+        Assert.assertEquals(nextCustomField.getFieldName(), SEARCHABLE_FILED_NAME);
+
+        nextCustomField = result.iterator().next();
+        Assert.assertEquals(nextCustomField.getObjectType(), ObjectType.ACCOUNT);
+        Assert.assertEquals(nextCustomField.getFieldName(), SEARCHABLE_FILED_NAME);
+
+
+        result = customFieldDao.searchCustomFields(SEARCHABLE_FILED_NAME, "The world will collapse soon!", ObjectType.ACCOUNT, 0L, 100L, internalCallContext);
+        Assert.assertEquals(result.getTotalNbRecords().longValue(), 1L);
+        Assert.assertEquals(result.getMaxNbRecords().longValue(), 5L);
+
+        nextCustomField = result.iterator().next();
+        Assert.assertEquals(nextCustomField.getObjectType(), ObjectType.ACCOUNT);
+        Assert.assertEquals(nextCustomField.getFieldName(), SEARCHABLE_FILED_NAME);
+        Assert.assertEquals(nextCustomField.getFieldValue(), "The world will collapse soon!");
+
+
+        result = customFieldDao.searchCustomFields(NON_SEARCHABLE_FILED_NAME, "The world will collapse soon!", ObjectType.ACCOUNT, 0L, 100L, internalCallContext);
+        Assert.assertEquals(result.getTotalNbRecords().longValue(), 0L);
+        Assert.assertEquals(result.getMaxNbRecords().longValue(), 5L);
+
+
+    }
+
+}