#Test
void testDepartment() throws Exception {
String nameParam1 = "ComputerScience";
String nameParam2 = "Department of Mathematics";
String nameParam3 = "Department of Music";
String nameParam4 = "Department of Language and Literature";
String locParam = "null";
List<Department> result = seacrhDepartment(nameParam1, nameParam2, nameParam3, nameParam4, locParam);
assertThat(result.size()).isEqualTo(0);
}
private List<Department> seacrhDepartment(String nameParam1, String nameParam2, String nameParam3, String nameParam4, String locParam) {
BooleanBuilder builder = new BooleanBuilder();
if (nameParam1 != null) {
builder.and(department.name.eq(nameParam1));
}
if (nameParam2 != null) {
builder.and(department.name.eq(nameParam2));
}
if (nameParam3 != null) {
builder.and(department.name.eq(nameParam3));
}
if (nameParam4 != null) {
builder.and(department.name.eq(nameParam4));
}
if (locParam != null) {
builder.and(department.name.eq(locParam));
}
return queryFactory
.selectFrom(department)
.where(builder)
.fetch();
}
#BeforeEach
public void before() {
queryFactory = new JPAQueryFactory(em);
Department department1 = new Department("ComputerScience");
Department department2 = new Department("Department of Mathematics");
Department department3 = new Department("Department of Music");
Department department4 = new Department("Department of Language and Literature");
em.persist(department1);
em.persist(department2);
em.persist(department3);
em.persist(department4);
}
I pre-entered the data.. But Why does isEqual(0) have to be passed here..?
Since all conditions were set to builder.and, wouldn't it pass when set to isEqualTo(5)?
And what test should I use to search for the word com and get a computerscience department?
There is no Department that satisfied all filters. You probably want to use builder.or instead of builder.and.
Related
I have getResponse() methods which build a response from data fetched from the database (or pre-saved in a SavedData object). I would like to find a way to abstract out the "check savedData" logic from my getResponse() methods. Ideally, I want to figure out a way where my getResponse() methods don't even know SavedData exists, it is just hidden behind some interface. Is there a good abstraction here I can use to clean up this code?
The following is just pseudo-code. For each field which is returned in the getResponse() JSON object, they first check if that field has been saved in some SavedData and use it if it has, otherwise, they need to query the DB for the field.
interface ResponseGetter {
public Response getResponse(String userID, SavedData savedData);
}
class A implements ResponseGetter {
public Response getResponse(String userID, SavedData savedData) {
List<String> foo;
int bar;
String bizz;
foo = savedData.get(userID, "foo");
if (foo == null) {
foo = loadFooFromDB(userID);
}
bar = savedData.get(userID, "bar");
if (bar == null) {
bar = loadBarFromDB(userID);
}
bizz = savedData.get(userID, "bizz");
if (bizz == null) {
bizz = loadBizzFromDB(userID);
}
JSONObject json = new JSONObject();
json.put("foo", foo);
json.put("bar", bar);
json.put("bizz", biz);
return new Response(json);
}
private List<String> loadFooFromDB(String userID) {
List<String> returnList = new ArrayList<String>();
DB db = this.getDB();
String query = "SELECT foo FROM SomeTable WHERE user_id=" + userID;
Results results = db.executeQuery(query);
for (Result result : results) {
returnList.add(result.toString());
}
return returnList;
}
}
class B implements ResponseGetter {
public Response getResponse(String userID, SavedData savedData) {
List<String> baz;
int qux;
String corge;
baz = savedData.get(userID, "baz");
if (baz == null) {
baz = loadBazFromDB(userID);
}
qux = savedData.get(userID, "qux");
if (qux == null) {
qux = loadQuxFromDB(userID);
}
corge = savedData.get(userID, "corge");
if (corge == null) {
corge = loadCorgeFromDB(userID);
}
JSONObject json = new JSONObject();
json.put("baz", baz);
json.put("qux", qux);
json.put("corge", corge);
return new Response(json);
}
}
I would use generics and the Strategy Design Pattern.
I didn't really know what types and classes you could give up, since you provided a pseudo-code.
If I forgot to put something importante, please comment.
But I would go with something like this:
interface ResponseGetter<R> {
R getResponse(String userId, String dataToCheck, SavedData<R> savedData, Function<String, R> lambda);
}
class DB<R> {
public R executeQuery(String query) {
return null;
}
}
interface SavedData<R> {
public R get(String userId, String name);
}
class SomeClass<R> implements ResponseGetter<R> {
#Override
public R getResponse(String userId, String dataToCheck, SavedData<R> savedData, Function<String, R> lambda) {
R checkedData = savedData.get(userId, dataToCheck);
return checkedData == null ? loadDataFromDB(userId, lambda) : checkedData;
}
public R loadDataFromDB(String userId, Function<String, R> lambda) {
return lambda.apply(userId);
}
}
class SavedDataImpl<R> implements SavedData<R> {
#Override
public R get(String userId, String name) {
return null;
}
}
class Main {
public static void main(String[] args) {
// foo
SomeClass<List<String>> someClass = new SomeClass<>();
SavedDataImpl<List<String> savedDataImpl = new SavedDataImpl<>();
DB<List<String>> db = new DB<>();
List<String> foo = someClass.getResponse("1", "foo", savedDataImpl, (String userId) -> {
List<String> result = db.executeQuery("SELECT foo FROM SomeTable WHERE user_id=" + userId);
return result;
});
// bar
SomeClass<Integer> someClassTwo = new SomeClass<>();
SavedDataImpl<Integer savedDataImplTwo = new SavedDataImpl<>();
DB<Integer> dbTwo = new DB<>();
Integer bar = someClassTwo.getResponse("1", "bar", savedDataImplTwo, (String userId) -> {
Integer result = dbTwo.executeQuery("SELECT bar FROM SomeTable WHERE user_id=" + userId);
return result;
});
// bizz
SomeClass<String> someClassThree = new SomeClass<>();
SavedDataImpl<String savedDataImplThree = new SavedDataImpl<>();
DB<String> dbThree = new DB<>();
String bizz = someClassThree.getResponse("1", "bizz", savedDataImplThree, (String userId) -> {
String result = dbThree.executeQuery("SELECT bizz FROM SomeTable WHERE user_id=" + userId);
return result;
});
Map json = new HashMap();
json.put("foo", foo);
json.put("bar", bar);
json.put("bizz", bizz);
}
}
That way you are abstracting the behavior of the how to get the data and wich data to get.
I just formatted the response in a Map for simplicity.
Hi i have to return the ResultMessage along with my object class in my below code.
public List<EmployeeInformation> findAll(String IndexName) throws Exception {
String ResultMessage = new String();
if (Strings.isNullOrEmpty(IndexName)) {
ResultMessage= "Index name is null or empty";
} else if (isTextContainUpperCase(IndexName)) {
ResultMessage= "Index name should be in lowercase";
} else if (!checkEsConnection(client)) {
ResultMessage= "Elasticsearch deployment is not reachable";
}
SearchRequest searchRequest = new SearchRequest(IndexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
return getSearchResult(searchResponse);
}
private List<EmployeeInformation> getSearchResult(SearchResponse response) {
SearchHit[] searchHit = response.getHits().getHits();
List<EmployeeInformation> EmployeeDocuments = new ArrayList<>();
for (SearchHit hit : searchHit) {
EmployeeDocuments
.add(objectMapper
.convertValue(hit
.getSourceAsMap(), EmployeeInformation.class));
}
return EmployeeDocuments;
}
What is the best way to return the ResultMessage along with my employeeinformation object. Could some one Modify the above code accordingly and post your answer or suggest me how to achieve this? thanks in advance
You can return ImmutablePair<ResultMessage, List<EmployeeInformation>>.
This objects then be accessed by getLeft() and getRight() methods. However, you will need org.apache.commons lib for this. It is worth adding this lib as it has many more such utils and wrapper classes. https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
This code is my suggested sample code for your requirement.
public class Test {
public static void main(String args[]) {
Test test = new Test();
String dept = "test";
Object[] result = test.searchUser(dept);
// Here must and should be follow the initailize order.
String something = null;
EmployeeInformation employee = null;
if (result.length>= 0 && result[0] instanceof String) {
something = (String) result[0];
}
if (result.length>= 1 && result[1] instanceof EmployeeInformation) {
employee = (EmployeeInformation) result[1];
}
// do something
}
public Object[] searchUser(String dept) {
Object[] result = new Object[2];
result[0] = dept;
result[1] = getUser(dept);
return result;
}
private List<EmployeeInformation> getUser(String dept) {
List<EmployeeInformation> userList = null;
// some logic for get the EmployeeInformationInformation List based on
// department.
return userList;
}
}
SITUATION
In the code below you can see 2 REST services which both should return a MessageVO. The first service (serviceThatDoesWork) returns a MessageVO as excpected, but the second service (serviceThatDoesNotWork) refuses to, it doesn't even give any output at all.
However returning a Response (java.ws.rs.core.Response) with serviceThatDoesNotWork does give an output. Even when I skip the 'doStuff'-methods and create a dummy-MessageVO that is exactly the same for each service, the 2nd one doesn't return anything.
QUESTION
Why does the 2nd service fail to return a MessageVO? It doens't return anything when I try returning a MessageVO, and nothing out of the ordinary appears in the logging.
The two services need to return exactly the same kind of thing but still one of them doesn't want to return anything, what am I not seeing here?
Could it be because of the path (and/or the amount of parameters)?
CODE
MyServices.java:
#Path("/myService")
...
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/myPath/{param1}/{param2}/{param3}")
public MessageVO serviceThatDoesWork(#PathParam("param1") Integer param1_id, #PathParam("param2") Integer param2_id, #PathParam("param2") Integer param2_id)
{
List<SomethingVO> lstO = MyRestServiceBusiness.doStuff(param1_id, param2_id, param3_id);
//return SUCCESS or FAIL message
MessageVO msg = new MessageVO();
if(lstO.size() > 0)
{
List<String> s = new ArrayList<String>();
for(SomethingVO k : lstO)
{
s.add(k.getId().toString());
}
msg.setItem_ids(s);
msg.setMsg("SUCCESS");
}
else
{
msg.setMsg("FAIL");
}
return msg;
}
...
#GET
#Path("/myPath/{param1}/{param2}/{param3}/{param4}/.../{param15}{a:(/a/[^/]+?)?}{b:(/b/[^/]+?)?}")
public Response serviceThatDoesNotWork(#PathParam("param1")Integer param1_id, ..., #PathParam("param15") Integer param15_id,
#PathParam("a") String a_id, #PathParam("b") String b_id)
{
//PUT 'OPTIONAL' PARAMS IN A LIST
List<Integer> lstI = new ArrayList<Integer>();
String aId = a_id != null ? a_id.split("/")[2] : null;
String bId = b_id != null ? b_id.split("/")[2] : null;
if(aId != null)
{
lstI.add(Integer.parseInt(aId ));
}
if(bId != null)
{
lstI.add(Integer.parseInt(bId ));
}
//DO STUFF
String afsId = "";
if(lstI.size() > 0)
{
afsId = MyRestServiceBusiness.doStuff(param1, ..., lstI);
}
//return SUCCESS or FAIL message
MessageVO msg = new MessageVO();
if(afsId != null && !afsId.isEmpty())
{
List<String> s = new ArrayList<String>();
s.add(afsId);
msg.setItem_ids(s);
msg.setMsg("SUCCESS");
}
else
{
List<String> s = new ArrayList<String>();
for(Integer i : lstI)
{
s.add(i.toString());
}
msg.setItem_ids(s);
msg.setMsg("FAIL");
}
//WENT THROUGH ALL ABOVE CODE AS EXPECTED, MESSAGEVO HAS BEEN FILLED PROPERLY
return msg;
}
CODE MessageVO.java:
#XmlRootElement
public class MessageVO
{
private String msg;
private List<String> item_ids;
//GETTERS
#XmlElement(name = "Message")
public String getMsg() {
return msg;
}
#XmlElement(name = "Item ID's")
public List<String> getItem_ids() {
return item_ids;
}
//SETTERS
public void setMsg(String msg) {
this.msg = msg;
}
public void setItem_ids(List<String> item_ids) {
this.item_ids = item_ids;
}
If I need to provide extra information please ask, this is my first attempt at (REST-) services.
As Vaseph mentioned in a comment I just forgot the #Produces annotation in the 2nd service.
How can we make a fulltext search with collectionId on Oracle UCM? Is it possible to do fulltext search supplying recursively start with collectionId parameter?
I did some trials (you can take a look below) but if i test with collectionId, there is no result return.
public List<UCMDocumentTemplate> fullTextSearchByFolderId(#WebParam(name = "searchCriteria")
String paramSearchCriteria, #WebParam(name = "ucmFolderId")
Long ucmFolderId) throws UCMDocumentSearchException
{
List<UCMDocumentTemplate> documentTemplateList = new ArrayList<UCMDocumentTemplate>();
String documentSearchCriteria = "";
try
{
if (ucmFolderId != null)
documentSearchCriteria = "xCollectionID <= <qsch>" + ucmFolderId + "</qsch> <AND>";
documentSearchCriteria += "dDocFullText <substring> <qsch>" + paramSearchCriteria + "</qsch>";
List<Properties> childDocumentList = UCM_API.fullTextSearch(documentSearchCriteria);
UCMDocumentTemplate ucmDocumentTemplate = null;
if (childDocumentList != null)
for (Properties properties : childDocumentList)
{
ucmDocumentTemplate = transformToUCMDocumentTemplate(new UCMDocumentTemplate(), properties);
documentTemplateList.add(ucmDocumentTemplate);
}
}
catch (Exception e)
{
UCMDocumentSearchException exc = new UCMDocumentSearchException(documentSearchCriteria, e);
System.err.println(exc.getCompleteCode());
e.printStackTrace();
throw exc;
}
return documentTemplateList;
}
public static List<Properties> fullTextSearch(String searchCriteria) throws Exception
{
List<Properties> resultList = null;
List<Field> fields = null;
Properties responseProperties = null;
Properties inputBinderProperties = new Properties();
inputBinderProperties.put("IdcService", "GET_SEARCH_RESULTS");
inputBinderProperties.put("QueryText", searchCriteria);
inputBinderProperties.put("SearchEngineName", "databasefulltext");
inputBinderProperties.put("ResultCount", "500");
DataBinder responseBinder = getExecutedResponseBinder(userName, inputBinderProperties);
DataResultSet resultSet = responseBinder.getResultSet("SearchResults");
fields = resultSet.getFields();
resultList = new ArrayList<Properties>();
for (DataObject dataObject : resultSet.getRows())
{
responseProperties = new Properties();
for (Field field : fields)
{
if (field.getType() == Field.Type.DATE && dataObject.getDate(field.getName()) != null)
responseProperties.put(field.getName(), dataObject.getDate(field.getName()));
else
responseProperties.put(field.getName(), dataObject.get(field.getName()));
}
resultList.add(responseProperties);
}
return resultList;
}
i found a solution. when adding a parameter to inputBinderProperties, it works properly
inputBinderProperties.put("folderChildren", ucmFolderId);
I am trying to create a Mock class for droplet. I am able to mock the repository calls and req.getParameter but need help on how to mock the repository item list from the repository. Below is the sample code.
for (final RepositoryItem item : skuList) {
final String skuId = (String) item.getPropertyValue("id");
final String skuType = (String) item.getPropertyValue("skuType");
if (this.isLoggingDebug()) {
this.logDebug("skuType [ " + skuType + " ]");
}
final String skuActive = (String) item.getPropertyValue("isActive");
if EJSD.equalsIgnoreCase(skuType) && (skuActive.equals("1"))) {
eSkuList.add(item);
skuCode = (String) item.getPropertyValue(ESTConstants.SKU_MISC1);
} else (PJPROMIS.equalsIgnoreCase(skuType) && skuId.contains("PP") && (skuActive.equals("1"))) {
personalSkuList.add(item);
String tmp = "";
if (skuId.lastIndexOf("-") > -1) {
tmp = skuId.substring(skuId.lastIndexOf("-") + 1);
tmp = tmp.toUpperCase();
if (this.getDefaultDisplayNameMap() != null) {
String val = this.getDefaultDisplayNameMap().get(tmp);
if (StringUtils.isNotEmpty(val)) {
displayNameMap.put(skuId, val);
} else {
val = (String) item.getPropertyValue("displayName");
displayNameMap.put(skuId, val);
}
} else {
final String val = (String) item.getPropertyValue("displayName");
displayNameMap.put(skuId, val);
}
}
}
}
There are a multitude of ways to 'mock' the list. I've been doing it this was as I feel it is more readable.
#Mock private RepositoryItem skuMockA;
#Mock private RepositoryItem skuMockB;
List<RepositoryItem> skuList = new ArrayList<RepositoryItem>();
#BeforeMethod(groups = { "unit" })
public void setup() throws Exception {
testObj = new YourDropletName();
MockitoAnnotations.initMocks(this);
skuList = new ArrayList<RepositoryItem>();
skuList.add(skuMockA);
skuList.add(skuMockB);
Mockito.when(skuMockA.getPropertyValue("id")).thenReturn("skuA");
Mockito.when(skuMockA.getPropertyValue("skuType")).thenReturn(ActiveSkuDroplet.EJSD);
Mockito.when(skuMockA.getPropertyValue(ESTConstants.SKU_MISC1)).thenReturn("skuCodeA");
Mockito.when(skuMockA.getPropertyValue("displayName")).thenReturn("skuADisplayName");
Mockito.when(skuMockB.getPropertyValue("id")).thenReturn("skuB-PP");
Mockito.when(skuMockB.getPropertyValue("skuType")).thenReturn(ActiveSkuDroplet.PJPROMIS);
Mockito.when(skuMockB.getPropertyValue(ESTConstants.SKU_MISC1)).thenReturn("skuCodeB");
Mockito.when(skuMockB.getPropertyValue("displayName")).thenReturn("skuBDisplayName");
}
So when you then call this within a test it will be something like this:
Mockito.when(someMethodThatReturnsAList).thenReturn(skuList);
So the key really is that you are not mocking the List but instead the contents of the List.
Creating a mock using mockito is a good option.
But I am here explaining a different way of mocking the repository item.
Create a common implementation for RepositoryItem, say MockRepositoryItemImpl like this in your test package.
Public MockRepositoryItemImpl implements RepositoryItem {
private Map<String, Object> properties;
MockRepositoryItemImpl(){
properties = new HashMap<>();
}
#override
public Object getPropertyValue(String propertyName){
return properties.get(propertyName);
}
#override
public void setPropertyValue(String propertyName, Object propertyValue){
properties.put(propertyName, propertyValue);
}
}
Use this implementation to create the mock object in your test case.
RepositoryItem mockSKU = new MockRepositoryItemImpl();
mockSKU.setPropertyValue("id", "sku0001");
mockSKU.setPropertyValue("displayName", "Mock SKU");
mockSKU.setPropertyValue("skuType", "Type1");
mockSKU.setPropertyValue("isActive", "1");