Specific query in java spring called from rest controller - java

I'm trying to filter a table called Measure through its field customerId. This is what the beginning of the controller for the path looks like:
#RequestMapping(method = GET, path = "/nodes/{id}/ports/{portid}/measures")
#ResponseBody
public ResponseEntity<?> getPortMeasures(#PathVariable long id, #PathVariable long portid,
#RequestParam Optional<Long> from,
#RequestParam Optional<String> order,
#RequestParam Optional<String> countername,
#RequestParam Optional<Long> to) {
Followed by the method that calls the query undernath
if (order.isPresent() && order.get().equals("asc")) {
return ResponseRestBuilder.createSuccessResponse(
measureRepository.
searchAsc
(networkElementList.get(0).ip, portList.get(0).rack, portList.get(0).frame, portList.get(0).slot,
portList.get(0).portSerial, countername.get(), from.orElse(0L), to.orElse(99999999999999999L)));
}
else{
return ResponseRestBuilder.createSuccessResponse(
measureRepository.
searchDesc
(networkElementList.get(0).ip, portList.get(0).rack, portList.get(0).frame, portList.get(0).slot,
portList.get(0).portSerial, countername.get(), from.orElse(0L), to.orElse(99999999999999999L)));
}
This is what the queries look like:
#Query("SELECT mes FROM Measure mes WHERE " +
"mes.nodeIp = (:nodeIp) AND " +
"mes.rack = (:rack) AND " +
"mes.frame = (:frame) AND " +
"mes.slot = (:slot) AND " +
"mes.portSerial = (:portSerial) AND " +
"lower(mes.counterName) LIKE concat('%', lower(:countername), '%') AND"+
"mes.timestamp > (:timestamp1) AND " +
"mes.timestamp < (:timestamp2) "+
"ORDER BY mes.timestamp DESC")
List<Measure> searchDesc(#Param("nodeIp") String nodeIp, #Param("rack") String rack, #Param("frame") String frame,
#Param("slot") String slot, #Param("portSerial") String portSerial, #Param("countername") String countername,
#Param("timestamp1") Long timestamp1, #Param("timestamp2") Long timestamp2);
#Query("SELECT mes FROM Measure mes WHERE " +
"mes.nodeIp = :nodeIp AND " +
"mes.rack = :rack AND " +
"mes.frame = :frame AND " +
"mes.slot = :slot AND " +
"mes.portSerial = :portSerial AND " +
"lower(mes.counterName) LIKE concat('%', lower(:countername), '%') AND " +
"mes.timestamp > :timestamp1 AND " +
"mes.timestamp < :timestamp2 "+
"ORDER BY mes.timestamp ASC")
List<Measure> searchAsc(#Param("nodeIp") String nodeIp, #Param("rack") String rack, #Param("frame") String frame,
#Param("slot") String slot, #Param("portSerial") String portSerial, #Param("countername") String countername,
#Param("timestamp1") Long timestamp1, #Param("timestamp2") Long timestamp2);
It's not filtering anything because the controller replies with 0 rows. I'm 100% confident there are actual rows because I've checked with other rest calls. What am I doing wrong?
EDIT: debug

Most probably the issue is with the timestamp field ,it seems from the code that you are passing a long, but actually it's waiting for a timestamp literal , timestamp literal in jpa is in the format {ts '2009-11-05 12-45-52.325'} ... just to check , try removing the timestamp from the query then put it again and provide the literals manually ... if it works, you then need to find a way to parse the passed long to the corresponding literal

The problem with it was the field portList.get(0).rack being "null". Appartently this made the whole query not work.

Related

Cannot convert a String to Decimal128 in #Query usgin Spel

I'm trying to do a convertion from String to Decimal128 in a #Query to perform a paging operation using the following snippet:
public interface ExpenseCollectionRepository extends ReactiveMongoRepository<ExpenseCollection, String> {
Mono<Boolean> existsByDescriptionAndDueDate(String description, LocalDate dueDate);
#Query("{'$or':" +
" [" +
"{'description': '?0'}," +
"{'value': '?#{#search.matches(\"-?\\\\d+(\\\\.\\\\d+)?\") ? T(org.bson.types.Decimal128).parse(#search) : T(org.bson.types.Decimal128).parse(\"0.0\")}}'}," +
"{'paymentDate': '?0'}," +
"{'dueDate': '?0'}," +
"{'type': '?0'}," +
"{'payed': '?0'}" +
"]" +
"}")
Flux<ExpenseCollection> findPage(#Param("search") String search, Pageable pageable);
}
What an I missing? Do I using Spel wrongly?
Github: https://github.com/SergioLuigi/expense-control/blob/bug/stack-over-flow-question/src/main/java/br/com/sergioluigi/expensecontroljava/expense/infrastructure/database/repository/ExpenseCollectionRepository.java

Indent lambda function body in Intellij

I have this example code that I want to pass some checkstyle rules but my formatter is not properly set up.
I just want an extra indent to lambda function body and change location of its right bracket }
This is what my code looks currently when I format it (Ctrl + Alt + L)
Optional.ofNullable(customerClient.
getActiveCustomers()).map(customer -> {
String firstName = customer.getFirstName();
String lastName = customer.getLastName();
return firstName + " " + lastName;
}).orElse(null);
but I need to change my formatter so that the code would look like this:
Optional.ofNullable(customerClient.
getActiveCustomers()).map(customer -> {
String firstName = customer.getFirstName();
String lastName = customer.getLastName();
return firstName + " " + lastName;
}
).orElse(null);
It's a known issue. Feel free to vote.

disassemble object in array

I have a search method in the database that brings me the following result:
As you see that inside the Object [4] comes another array containing People, Pessoas, and PessoasEnderecos and more objects that have relantionship with Pessoas.
I would like it to return only this way and not inside another array as it is happening now, it should look like this:
elementData=Object[10](id=144)
[0]=Pessoas(id=166)
[1]=PessoasEnderecos(id=167)
...
i have this method:
#RequestMapping(method = RequestMethod.GET, value = "/pessoas")
public ResponseEntity<Collection<Pessoas>> buscarPessoas(HttpServletRequest request) throws Exception {
String idEntidadeCrypt = request.getHeader("DataBase");
Long idEntidade = Long.parseLong(Crypto.decode(idEntidadeCrypt));
Collection<Pessoas> pessoasBuscados = pessoasService.buscarFiltro(idEntidade);
return new ResponseEntity<>(pessoasBuscados, HttpStatus.OK);
}
and :
#Repository
public interface PessoasRepository extends JpaRepository<Pessoas, Integer> {
#Query( value="select pes, pEnd, pFis, pJur "
+ "from "
+ "Pessoas pes, "
+ "PessoasEnderecos pEnd,"
+ "PessoasFisicas pFis,"
+ "PessoasJuridicas pJur"
+ " where "
+ "pes.entidade.idEntidade = pEnd.entidade.idEntidade "
+ "and pes.idPessoa = pEnd.pessoa.idPessoa "
+ "and pes.entidade.idEntidade = pFis.entidade.idEntidade "
+ "and pes.idPessoa = pFis.pessoa.idPessoa "
+ "and pes.entidade.idEntidade = pJur.entidade.idEntidade "
+ "and pes.idPessoa = pJur.pessoa.idPessoa "
+ "and pes.entidade.idEntidade = :parametroId " )
public Collection<Pessoas> encontrar(#Param("parametroId") Long usuarioEntidade);
how can i solve that ?
ArrayList<> does not work with magic, it has an actual implementation. elementData is the array where it stores its elements. As you can see (that is a link in the previous sentence), it is a private member of the class, so you do not interact with it, but you see it in a debugger because it exists.
If you want to return an array instead of a List, you can always use toArray() which all Lists implement.

Extracting Capture Group from Non-Capture Group in Java

I have a string, let's call it output, that's equals the following:
ltm data-group internal str_testclass {
records {
baz {
data "value 1"
}
foobar {
data "value 2"
}
topaz {}
}
type string
}
And I'm trying to extract the substring between the quotes for a given "record" name. So given foobar I want to extract value 2. The substring I want to extract will always come in the form I have prescribed above, after the "record" name, a whitespace, an open bracket, a new line, whitespace, the string data, and then the substring I want to capture is between the quotes from there. The one exception is when there is no value, which will always happen like I have prescribed above with topaz, in which case after the "record" name there will just be an open and closed bracket and I'd just like to get an empty string for this. How could I write a line of Java to capture this? So far I have ......
String myValue = output.replaceAll("(?:foobar\\s{\n\\s*data "([^\"]*)|()})","$1 $2");
But I'm not sure where to go from here.
Let's start extracting "records" structure with following regex ltm\s+data-group\s+internal\s+str_testclass\s*\{\s*records\s*\{\s*(?<records>([^\s}]+\s*\{\s*(data\s*"[^"]*")?\s*\}\s*)*)\}\s*type\s*string\s*\}
Then from "records" group, just find for sucessive match against [^\s}]+\s*\{\s*(?:data\s*"(?<data>[^"]*)")?\s*\}\s*. The "data" group contains what's you're looking for and will be null in "topaz" case.
Java strings:
"ltm\\s+data-group\\s+internal\\s+str_testclass\\s*\\{\\s*records\\s*\\{\\s*(?<records>([^\\s}]+\\s*\\{\\s*(data\\s*\"[^\"]*\")?\\s*\\}\\s*)*)\\}\\s*type\\s*string\\s*\\}"
"[^\\s}]+\\s*\\{\\s*(?:data\\s*\"(?<data>[^\"]*)\")?\\s*\\}\\s*"
Demo:
String input =
"ltm data-group internal str_testclass {\n" +
" records {\n" +
" baz {\n" +
" data \"value 1\"\n" +
" }\n" +
" foobar {\n" +
" data \"value 2\"\n" +
" }\n" +
" topaz {}\n" +
" empty { data \"\"}\n" +
" }\n" +
" type string\n" +
"}";
Pattern language = Pattern.compile("ltm\\s+data-group\\s+internal\\s+str_testclass\\s*\\{\\s*records\\s*\\{\\s*(?<records>([^\\s}]+\\s*\\{\\s*(data\\s*\"[^\"]*\")?\\s*\\}\\s*)*)\\}\\s*type\\s*string\\s*\\}");
Pattern record = Pattern.compile("(?<name>[^\\s}]+)\\s*\\{\\s*(?:data\\s*\"(?<data>[^\"]*)\")?\\s*\\}\\s*");
Matcher lgMatcher = language.matcher(input);
if (lgMatcher.matches()) {
String records = lgMatcher.group();
Matcher rdMatcher = record.matcher(records);
while (rdMatcher.find()) {
System.out.printf("%s:%s%n", rdMatcher.group("name"), rdMatcher.group("data"));
}
} else {
System.err.println("Language not recognized");
}
Output:
baz:value 1
foobar:value 2
topaz:null
empty:
Alernatives: As your parsing a custom language, you can give a try to write an ANTLR grammar or create Groovy DSL.
Your regex shouldn't even compile, because you are not escaping the " inside your regex String, so it is ending your String at the first " inside your regex.
Instead, try this regex:
String regex = key + "\\s\\{\\s*\\n\\s*data\\s*\"([^\"]*)\"";
You can check out how it works here on regex101.
Try something like this getRecord() method where key is the record 'name' you're searching for, e.g. foobar, and the input is the string you want to search through.
public static void main(String[] args) {
String input = "ltm data-group internal str_testclass { \n" +
" records { \n" +
" baz { \n" +
" data \"value 1\" \n" +
" } \n" +
" foobar { \n" +
" data \"value 2\" \n" +
" }\n" +
" topaz {}\n" +
" } \n" +
" type string \n" +
"}";
String bazValue = getRecord("baz", input);
String foobarValue = getRecord("foobar", input);
String topazValue = getRecord("topaz", input);
System.out.println("Record data value for 'baz' is '" + bazValue + "'");
System.out.println("Record data value for 'foobar' is '" + foobarValue + "'");
System.out.println("Record data value for 'topaz' is '" + topazValue + "'");
}
private static String getRecord(String key, String input) {
String regex = key + "\\s\\{\\s*\\n\\s*data\\s*\"([^\"]*)\"";
final Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
//if we find a record with data return it
return matcher.group(1);
} else {
//else see if the key exists with empty {}
final Pattern keyPattern = Pattern.compile(key);
Matcher keyMatcher = keyPattern.matcher(input);
if (keyMatcher.find()) {
//return empty string if key exists with empty {}
return "";
} else {
//else handle error, throw exception, etc.
System.err.println("Record not found for key: " + key);
throw new RuntimeException("Record not found for key: " + key);
}
}
}
Output:
Record data value for 'baz' is 'value 1'
Record data value for 'foobar' is 'value 2'
Record data value for 'topaz' is ''
You could try
(?:foobar\s{\s*data "(.*)")
I think the replaceAll() isn't necessary here. Would something like this work:
String var1 = "foobar";
String regex = '(?:' + var1 + '\s{\n\s*data "([^"]*)")';
You can then use this as your regex to pass into your pattern and matcher to find the substring.
You can simple transform this into a function so that you can pass variables into it for your search string:
public static void SearchString(String str)
{
String regex = '(?:' + str + '\s{\n\s*data "([^"]*)")';
}

Java - RegEx pattern that consists of LDAP attributes

Is there a way to use LDAP attributes stored in Strings as the RegEx pattern?
I am thinking something like this:
PASSWORD_WITH_LDAP_ATTRIBUTE = Pattern.compile(userid + "|" + ssn + "|" + bdate + "|" + empNo + "|" + telNo);
I already tried this one out. In any string that I input, the regex always finds a match even though its not a clear match.
Is this possible or am I venturing to the impossible?
Here is the whole method:
private static Pattern PASSWORD_WITH_LDAP_ATTRIBUTE = null;
private boolean checkForLdapAttributes(final String newPassword) throws LDAPException{
LoggingEnt loggingEnt = new LoggingEnt();
String userid = loggingEnt.getUseridCode();
String ssn = loggingEnt.getSocialSecurityNumber();
String bdate = loggingEnt.getBirthDate();
String empNo = loggingEnt.getEmployeeNumber();
String telNo = loggingEnt.getTelephoneNumber();
PASSWORD_WITH_LDAP_ATTRIBUTE = Pattern.compile(userid + "|" + ssn + "|" + bdate + "|" + empNo + "|" + telNo);
matcher = PASSWORD_WITH_LDAP_ATTRIBUTE.matcher(newPassword);
if(PASSWORD_WITH_LDAP_ATTRIBUTE.matcher(newPassword).find()){
isPasswordAccepted = false;
loggingEnt.setMsg1("You cannot use any of your Username, Social Security No., Birthdate, Employee No., and Telephone No. as password.");
throw new LDAPException("Invalid password combination for " + userid, LDAPException.INVALID_CREDENTIALS);
} else {
loggingEnt.setMsg1("Password accepted.");
isPasswordAccepted = true;
}
return matcher.matches();
}
You're doing this wrong. You're not supposed to match the password attribute yourself. You are supposed to attempt to 'bind' to LDAP specifying a username and password, and it will match the password for you. Or not.
In JNDI, 'bind' corresponds to LdapContext.reconnect().

Categories

Resources