How to paginate in spring ldap using skip value - java

Can any body help me on how I can find some record from LDAP using springldap.
My problem is, I have created a rest service and it accepts some parameter. One is offset and another is limit. Offset parameter escape some record like if my ldap server have 500 record.
Now if I give offset value 1 and LIMIT is 100. then it should give first 100 record from ldap.
If I give offset value 100 and LIMIT is 100, then it should give 100 record after first 100 record from ldap.
If I give offset value 50 and LIMIT is 10, then it should give 10 record after first 50 record from ldap.
I am stuck on how to set offset value in spring ldap template. I have set limit value and it is working fine.
I am sharing peace of code.
public OrganisationGroups getOrganisationGroup()
{
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
controls.setCountLimit(MAXIMUM_SEARCH_GROUP_COUNT);
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
List<OrganisationGroup> organisationGroup = ldapTemplate.search("", filter.toString(), controls, new GroupSearchMapper());
OrganisationGroups groups = new OrganisationGroups();
groups.setOrganisationGroup(organisationGroup);
groups.setCount(organisationGroup.size());
return groups;
}
In this code I have set MAXIMUM_SEARCH_GROUP_COUNT variable to find out maximum record from ldap. But I am not able to set parameter or any other way to escape some records from beginning.

Your best option is to use the Virtual List View request control (link to specification) also known as VLV. Note that to use VLV, you will need to make configuration changes on your LDAP server (I assume you are using OpenDJ, which supports VLV).
There is a code example for JNDI LDAP provider with the VLV request control at this forum.

Related

DataTables server-side pagination

I have working Spring REST app with client side pagination, default by DataTables and everything works. Now i need to change it to server-side pagination i have problem, because have no idea how to get information from DataTables what page number client want to see. I can't find anything usefull in DT manual.
When you say Datatable I assume you are talking about DataTables jQuery plugin.
To activate serverside pagination you need to pass
"serverSide": true,
like this:
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "/your_url"
});
Doing the above will activate your server-side pagination. But you need to do few changes on the server-side too. Let's see them step by step.
1. What happens when you mark serverSide as true
DataTables plugin adds custom parameters to the AJAX call with information like
order: asc
start: 20
length: 10
// and many more.
You can inspect this demo link and see the parameters passed in request when you click the next page button.
2. Similarly, DataTables plugin expects some fields in response in order to preserve pagination logic.
"draw": 3, // unique ID
"recordsTotal": 57, // total number of records
"recordsFiltered": 57 // total number of filtered records
You can inspect this demo link and see response data this time.
3. Now changes are on serverside in your API
You need to add these parameters as queryParam for GET and attr in POST call in your controller API:
order: asc
start: 20
length: 10
4. Service Layer Changes - DB query
In-Service Layer where you get details from a database.
You need to get the total number of records and in search query pass a LIMIT clause LIMIT 10, 10 in case of MySQL.
E.g.:
SELECT * FROM User LIMIT 20,10;
Use start and length to calculate the next set of records.
It can be trickier but if you understand and implement properly it's fun.
Read more in detail here which also contains code and live demo.
Please see the sample about DataTables server-side processing:
https://datatables.net/examples/server_side/simple.html
After change page, you can capture the request to server as following format:
https://.../server_processing.php?draw=3&columns...&order=0&dir=asc&start=20&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&_=1534436781912
That means DataTable requests page number 3 (draw=3), order by first column ascending, ....
At server side (REST), you can get page number by (for example) request.getParameter("draw")

Hiding information for a particular user

I am using RESTFUL webservices using Spring framework.Some information is displayed on the user interface using the data returned by webservices. There is a webservice, which gets the usernames and their roles from the database. For a particular user , I would like to have all the webservices display data in the form of ####,#### for first name,lastname ; ##/##/#### for date of birth etc. Since I am using JDBC to connect to the database, here's what I was thinking of doing:
Should I consider passing an additional parameter (maybe sending a value 0 or 1 ; 0 for all other users and 1 for user for which I want to hide the information) to each and every GET webservice so that when it comes to getting data from the database in the JDBC code part,I could check whether the flag is set to 1 or 0 and based on this, I could do something like this in the JDBC code :
// Code for a case when flag is set to `0`. Hence retrieving information from the database.
while(rs.next()) {
EmployeeList empList = new EmployeeList();
empList.setEmpId(empId);
empList.setEmployeeName(rs.getString("name"));
employeeList.add(empList);
}
// Code for a case when flag is set to `1`. Hence hiding information and not retrieving information from the database.
while(rs.next()) {
EmployeeList empList = new EmployeeList();
empList.setEmpId(empId);
empList.setEmployeeName("####,######");
employeeList.add(empList);
}
I am wondering, if this is an appropriate way to achieve my task or is there some other way around?
Edit:More clarifications on my requirements:
I am using jqxWidget in the UI to display the information I am getting from a RESTFUL webservice in JSON format. For example, let's consider this example and the screenshot for better understanding of my requirement:
1) Let's say I am getting all the information from the JSON response which I am populating in the jQXWidget as shown in the screenshot above.
2) In the above widget, I would like to hide say for example, First Name, Last Name and Quantity like the following:
First Name = XXXXX
Last Name = XXXXX
Quantity = ####
In my application, if a user clicks on a particular row , a new page is displayed with some additional information. After click, new sets of web services are called and those web services takes First Name, Last Name and Quantity as input parameters. My concern is that, if I somehow replace the First Name with XXXXX, Last Name with XXXXX and Quantity with #### using any approach, when a user clicks on any of the row of the widget, the next set of web services
are going to get XXXX and #### as input and eventually will fail. Please correct me if my understanding until this point is not correct.
Thanks
I am using Spring 4.2.5 version.
This depends on what sort of information hiding you want to achieve. Typically you shouldn't do this manually.
You can use, for example, role-based authorization. Exact details depends on the web-service framework you are using.
For spring MVC, you can use something similar to this:
Custom authorization in Spring MVC

Dynamodb AWS Java scan withLimit is not working

I am trying to use the DynamoDBScanExpression withLimit of 1 using Java aws-sdk version 1.11.140
Even if I use .withLimit(1) i.e.
List<DomainObject> result = mapper.scan(new DynamoDBScanExpression().withLimit(1));
returns me list of all entries i.e. 7. Am I doing something wrong?
P.S. I tried using cli for this query and
aws dynamodb scan --table-name auditlog --limit 1 --endpoint-url http://localhost:8000
returns me just 1 result.
DynamoDBMapper.scan will return a PaginatedScanList - Paginated results are loaded on demand when the user executes an operation that requires them. Some operations, such as size(), must fetch the entire list, but results are lazily fetched page by page when possible.
Hence, The limit parameter set on DynamoDBScanExpression is the maximum number of items to be fetched per page.
So in your case, a PaginatedList is returned and when you do PaginatedList.size it attempts to load all items from Dynamodb, under the hood the items were loaded 1 per page (each page is a fetch request to DynamoDb) till it get's to the end of the PaginatedList.
Since you're only interested in the first result, a good way to get that without fetching all the 7 items from Dynamo would be :
Iterator it = mapper.scan(DomainObject.class, new DynamoDBScanExpression().withLimit(1)).iterator();
if ( it.hasNext() ) {
DomainObject dob = (DomainObject) it.next();
}
With the above code, only the first item will fetched from dynamodb.
The take away is that : The limit parameter in DynamoDBQueryExpression is used in the pagination purpose only. It's a limit on the amount of items per page not a limit on the number of pages that can be requested.

What does this methods do?

I'm new to connecting Java to SQL Server but hopefully I manage to connect them successfully through helps of various tutorials. But there are these methods and syntax that I couldn't explain for myself.
1.
Connection conn=DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=login_DB;integratedSecurity=true");
Regarding the code above, what does integratedSecurity=true do?
2.
String user = rss.getString(1);
String pass = rss.getString(2);
Does the parameter inside getString(1) and getString(2) pertains to the column in the Database? And also, how does the ResultSet affects the getString()?
3.
while(rss.next()){
String user = rss.getString(1);
String pass = rss.getString(2);
if(usernameTF.getText().trim().equals(user)&&passwordTF.getText().trim().equals( pass)){
count = 1;
}//if success
}//while
Lastly, at least for now, does the while(rss.next()) method simply means that while there is a row in my table?
I know my code is a bad practice. But I am really trying my best to make it better.
Integrated Security = true/SSPI : the current Windows account credentials are used for authentication.
Integrated Security = False : User ID and Password are specified in the connection String.
rs.getString(1) - get 1 return column from your select statement.
Select x,y,z from table; rs.getString(1) gives x column result for particular row.
Your query returning n number row ,each time rs.next() check is there row available after current row.
Difference between Integrated Security = True and Integrated Security = SSPI
Yes the number refers to the column number, or you can pass a String as the column name to pull data.
Yes, whilst there is data in your ResultSet, for each iteration it will move the cursor to the next row of data available. Where you can access columns specifically using the syntax from part 2 of your question.
Hope this is useful.
According to Microsoft they are the same thing.
When false, User ID and Password are specified in the connection. When true, the current Windows account credentials are used for authentication.
Recognized values are true, false, yes, no, and sspi (strongly recommended), which is equivalent to true.
There however is a difference between them according to the comment below:
True ignores User Id and Password if provided and uses those of the running process, SSPI it will use them if provided which is why MS prefers this.
They are equivalent in that they use the same security mechanism to authenticate but that is it.
refer this link...!

GAE: Exception while allocating 16 digit ids

I notice problem with allocating IDs on google app engine while using datastore. In my application I have a set of data that have to be initially uploaded. Data has been prepared on test appengine environment so it has autogenerated values for ID fields. Since I want to preserve these values I'm recreating entities by using remote API with Objectify as a separate process. After upload I want to make sure that used IDs will be removed from value range for autogenerator. I'm using DatastoreService.allocateIdRange with range of single long value. Everything works fine on dev server but on appspot for some values (16 digits values) I receive "Exceeded maximum allocated IDs" IllegalArgumentException.
Is there any limitation of allocateIdRange call (I have found none in documentation)?
Below is a sample code I'm using for id allocation for datastore after upload:
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
String kind = Key.getKind(clazz);
PreparedQuery query = datastore.prepare(new Query(kind).setKeysOnly());
KeyRange keyRange = null;
Long id = null;
for (Entity entity : query.asIterable()) {
id = (Long) entity.getKey().getId();
keyRange = new KeyRange(null, kind, id, id);
DatastoreService.KeyRangeState state = datastore.allocateIdRange(keyRange);
}
This is a known issue with allocateIdRange(). A better error message would be "You can't call allocateIdRange() on scattered ids".
Scattered ids are the default since 1.8.1 and have values >= 2^52. Unfortunately we don't currently expose an API to reserve these ids.
It sounds like you may be trying to allocate an ID larger than the max allowed ID. This is limited by the largest integer size in javascript, which is 2^53.
Here is the page describing the App Engine limitation and the largest javascript int.

Categories