#Reference Object Query in Morphia using MongoDB - mongodb

I got two Entities :
public class UserAccount extends BaseEntity {
#Expose
#Property("username")
#Indexed(value = IndexDirection.ASC, name = "userNameIndex", unique = true)
private String userName = new String();
#Expose
#Property("password")
private String password = new String();
}
and
public class UserProfile extends BaseEntity {
#Expose
#Property("first name")
#Indexed(value = IndexDirection.ASC, name = "firstNameIndex")
private String firstName = new String();
#Expose
#Property("middle name")
// #Indexed(value = IndexDirection.ASC, name = "middleNameIndex")
private String middleName = new String();
#Expose
#Property("last name")
#Indexed(value = IndexDirection.ASC, name = "lastNameIndex")
private String lastName = new String();
#Expose
#Reference(/* idOnly = true, */value = "user id" /* , lazy = true */)
private UserAccount userAccount = new UserAccount();
}
I am trying to search all Users based on searched UserName (contains! but unique) and UsedProfileObjectId (#Id). I am trying to constraint check while saving userdetails if the provided username is Unique or not? (I need to check it in both new add and update cases). So I tried to code this:
public List<UserProfile> findAllUsersWithSameUserName(ObjectId id,
String userName) {
Datastore ds = getDatastore();
Query<UserProfile> profileQuery = ds.createQuery(UserProfile.class);
Query<UserAccount> accountQuery = ds.createQuery(UserAccount.class);
accountQuery.criteria("username").containsIgnoreCase(userName);
container.add(profileQuery.criteria("user id").in(
accountQuery.asKeyList()));
return profileQuery.asList();
}
But this code is showing
java.lang.NullPointerException
Am I missing something on code?
Also I try to enforce
#Reference(value = "user id", lazy = true)
private UserAccount userAccount = new UserAccount();
But, I got no clue how to rebind those Object with NO Data?
I tried to do this:
user = userProfileDAO.findUserByProfileID(id);
user.getUserAccount();
user.getUserAccount().getUserName();
user.getUserAccount().getPassword();
// Gson gson = new Gson();
// .setDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz").create();
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd")
.excludeFieldsWithoutExposeAnnotation().setPrettyPrinting()
.create();
response = gson.toJson(user, UserProfile.class);
Still the reponse got EMPTY UserAccount Data:
"userAccount": {
"userName": "",
"password": "",
"isDeleted": false,
"isActive": false,
"addedOn": "2015-08-06"
},
Even though on inspection I can get actual data like this: user.getUserAccount().getUserName()
Could not find any good example of using lazy=true in Morphia too? How can I enforce this lazy effect on my code?

This is a way how #Reference Object Query need to be done:
public UserProfile findAllUsersWithSameUserName(ObjectId id, String userName) {
Datastore ds = getDatastore();
Query<UserProfile> profileQuery = ds.createQuery(UserProfile.class);
Query<UserAccount> accountQuery = ds.createQuery(UserAccount.class);
accountQuery.criteria("username").hasThisOne(userName.toString());
profileQuery.and(profileQuery.criteria("_id").notEqual(id),
profileQuery.criteria("user id").in(accountQuery.asKeyList()));
return profileQuery.get();
}

Related

mtom does not work, classes are generated by Apache CXF,

It is not possible to optimize the SOAP packet, the data is transmitted. What am I doing wrong?
Generated client classes using JBDS. I looked through a lot of examples it is not possible to implement the ability to transfer files outside the package:
</ SOAP-ENV: Envelope>
---- boundary388.5294117647058824932.470588235294118--
Content-Id: <1.B1150656.EC8A.4B5A.8835.A932E318190B>
Content-Transfer-Encoding: binary
CONTENT-TYPE: application / octet-stream
..........
I change the parameters, but it always turns out like this:
<ns2:AttachmentContentList>
<ns2:AttachmentContent>
<ns2:Id>request.zip</ns2:Id>
<ns2:Content>UEsDBBQACAg......
////
Client:
SMEVMessageExchangeService service1 = null;
SMEVMessageExchangePortType port1 = null;
try {
service1 = new SMEVMessageExchangeService(wsdlLocation, SERVICE);
boolean enabled = true;
int threshold = 10240;
port1 = service1.getSMEVMessageExchangeEndpoint(new MTOMFeature(enabled, threshold));//!!!!
.......
AttachmentContentList acList = new AttachmentContentList();
AttachmentContentType aContentType = new AttachmentContentType();
aContentType.setId("request.zip");
BindingProvider bp = (BindingProvider) port1;
javax.xml.ws.soap.SOAPBinding binding2 = (javax.xml.ws.soap.SOAPBinding) bp.getBinding();
binding2.setMTOMEnabled(true);
System.out.println("_____binding2.isMTOMEnabled() - "+binding2.isMTOMEnabled());
DataSource source = new FileDataSource(reqPthFile);
//DataHandler dh =new DataHandler(source,"application/octet-stream");
DataHandler dh =new DataHandler(source);
aContentType.setContent(dh);
//////
#MTOM(enabled=true)
#BindingType(value = javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING)
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "AttachmentContentType", propOrder = {
"id",
"content"
})
public class AttachmentContentType {
#XmlElement(name = "Id", required = true)
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
#XmlID
#XmlSchemaType(name = "ID")
protected String id;
#MTOM(enabled=true)
#XmlElement(name = "Content", required = true)
#XmlMimeType("application/octet-stream")
protected DataHandler content;
public DataHandler getContent() {
return content;
}
public void setContent(DataHandler value) {
this.content = value;
}
///////
#MTOM(enabled=true)
#BindingType(value = javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING)
#WebService(targetNamespace = "urn://x-artefacts-smev-gov-ru/services/message-exchange/1.2", name = "SMEVMessageExchangePortType")
#XmlSeeAlso({ru.it.smev.message_exchange.autogenerated.types.v1_2.ObjectFactory.class, ru.it.smev.message_exchange.autogenerated.types.fault.v1_2.ObjectFactory.class, ru.it.smev.message_exchange.autogenerated.types.basic.v1_2.ObjectFactory.class})
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface SMEVMessageExchangePortType {
///////
#MTOM(enabled=true)
#BindingType(value = javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING)
#WebServiceClient(name = "SMEVMessageExchangeService",
targetNamespace = "urn://x-artefacts-smev-gov-ru/services/message-exchange/1.2")
public class SMEVMessageExchangeService extends Service {
Problem found.
MTOM stops working if handlerList is added.
Please tell me how you can use both handlerList and MTOM at the same time?
List<Handler> handlerList = binding.getHandlerChain();
// handlerList.add(new Handler1());
// handlerList.add(new Handler2());
handlerList.add(handler1);
handlerList.add(handler2);
binding.setHandlerChain(handlerList);

Search internal substrings in hibernate search

I've defined my entity as following.
#Entity
#Indexed
#AnalyzerDef(name = "ngram_index", tokenizer = #TokenizerDef(factory = WhitespaceTokenizerFactory.class),
filters = {
#TokenFilterDef(factory = LowerCaseFilterFactory.class),
#TokenFilterDef(factory = ASCIIFoldingFilterFactory.class),
#TokenFilterDef(factory = NGramFilterFactory.class,
params = {
#Parameter(name = SearchConstants.MIN_GRAM_SIZE_NAME, value = SearchConstants.MIN_GRAM_SIZE_VALUE),
#Parameter(name = SearchConstants.MAX_GRAM_SIZE_NAME, value = SearchConstants.MAX_GRAM_SIZE_VALUE)
})
})
#AnalyzerDef(name = "ngram_query", tokenizer = #TokenizerDef(factory = WhitespaceTokenizerFactory.class),
filters = {
#TokenFilterDef(factory = LowerCaseFilterFactory.class),
#TokenFilterDef(factory = ASCIIFoldingFilterFactory.class),
})
#NormalizerDef(name = "lowercase",
filters = {
#TokenFilterDef(factory = ASCIIFoldingFilterFactory.class),
#TokenFilterDef(factory = LowerCaseFilterFactory.class)
}
)
#Table(name = "ORDER")
public class Order {
#Id
#DocumentId
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Field(analyzer = #Analyzer(definition = "ngram_index"))
#Field(name = "name_Sort", store = Store.YES, normalizer= #Normalizer(definition="lowercase"))
#SortableField(forField = "name_Sort")
#Column(name = "NAME")
private String name;
//other fields, getters and setters omitted for brevity
I then tried to overwrite the default analyzer that is being used during indexing for querying in another class that is not an entity.
public abstract class AbstractHibernateSearcher<S extends SearchableEntity> {
// other fields and methods omitted here
protected Query buildInputSearchQuery(String[] searchableFields) {
if(Strings.isNullOrEmpty(searchRequest.getQuery()) || searchableFields.length == 0) {
return null;
}
SimpleQueryStringMatchingContext simpleQueryStringMatchingContext = queryBuilder.simpleQueryString().onField(searchableFields[0]);
for(int i = 1; i < searchableFields.length; i++) {
simpleQueryStringMatchingContext = simpleQueryStringMatchingContext.andField(searchableFields[i]);
}
Query inputSearchQuery = simpleQueryStringMatchingContext
.withAndAsDefaultOperator()
.matching((searchRequest.getQuery()).toLowerCase()).createQuery();
QueryBuilder queryBuilder = getNGramQueryBuilder(searchableFields);
return queryBuilder.bool().must(inputSearchQuery).createQuery();
}
protected QueryBuilder getNGramQueryBuilder(String[] searchFields) {
if (searchFields.length == 0) {
return null;
}
EntityContext entityContext = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(clazz);
for(String field : searchFields) {
entityContext = entityContext.overridesForField(field, "ngram_query");
}
return entityContext.get();
}
}
This gives me the following error when I do a query search.
{message: "HSEARCH000353: Unknown analyzer: 'ngram_query'. Make sure you defined this analyzer.",…}
exception: "RuntimeException"
message: "HSEARCH000353: Unknown analyzer: 'ngram_query'. Make sure you defined this analyzer."
I found this from the official document.
You can use #AnalyzerDef on any:
#Indexed entity regardless of where the analyzer is applied to;
parent class of an #Indexed entity;
package-info.java of a package containing an #Indexed entity.
Since I am seeing the unknown analyzer, I guess the class where I tried to overwrite with "ngram_query" analyzer has no visiblity on this analyzer?
Yes, you can create ngrams for each word: use a WhitespaceTokenizerFactory for your tokenizer, and add NGramFilterFactory to your token filters (note it's not the same class you mentioned: it's a token filter, not a tokenizer).
You will also need to use a different analyzer at query time, one that does not create ngrams. Otherwise a user typing "manhantan" may get a match for documents containing "man", for example.
See https://stackoverflow.com/a/56107399/6692043 for information on how to do that.
Note that ngrams can lead to very large indexes, especially if you're not careful with the value of the "minGramSize" and "maxGramSize" parameters.
Another solution would be to use your original analyzer and a wildcard query, but unfortunately it ignores analysis and can be quite slow when using leading wildcards (which is what you need here).
protected Query inputFilterBuilder() {
String[] searchableFields = getSearchableFields();
if(searchableFields.length == 0) {
return null;
}
TermMatchingContext termMatchingContext = queryBuilder.keyword().wildcard().onField(searchableFields[0]);
for(int i = 1; i < searchableFields.length; i++) {
termMatchingContext = termMatchingContext.andField(searchableFields[i]);
}
return termMatchingContext
.matching(("*" + searchRequest.getQuery() + "*").toLowerCase()).createQuery();
}
Note the code above will only work if there is a single search term. As soon as there are spaces in searchRequest.getQuery(), you won't get any result. There can be spaces in the indexed text, however, which is what you wanted, if I understood correctly.

Seed data to UserRole table .net core

I want to seed the default DB with an admin user before I start the project on .NET Core Default MVC application. The code is as below:
public void SeedDb(ApplicationDbContext Context, IServiceProvider ServiceProvider, IConfiguration Configuration)
{
if (Context.Users.Count() > 0) return;
var UserManager = ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var ApplicationUser = new ApplicationUser()
{
Email = Configuration["Email"],
NormalizedEmail = Configuration["Email"],
LockoutEnabled = false,
NormalizedUserName = Configuration["Email"],
SecurityStamp = "579355dd - a64c - 498d - a0b5 - 9e55754c9109",
EmailConfirmed = true,
ConcurrencyStamp = null,
Id = "977ec1a5-1ae7-4658-952a-6b5dccd75a85",
PasswordHash ="",
PhoneNumber = "333333333333",
LockoutEnd = null,
AccessFailedCount = 1,
PhoneNumberConfirmed = true,
TwoFactorEnabled = false,
UserName = Configuration["Email"]
};
var Password = HashPassword(ApplicationUser, Configuration["Password"]);
if (VerifyHashedPassword(ApplicationUser, Password, Configuration["Password"]) == PasswordVerificationResult.Success)
{
ApplicationUser.PasswordHash = Password;
}
Context.Users.Add(ApplicationUser);
Context.SaveChanges();
var RoleManager = ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
string[] Roles = { "Admin", "Manager", "User" };
foreach (string RoleName in Roles) {
RoleManager.CreateAsync(new IdentityRole(RoleName));
}
var Admin = Context.Users.SingleOrDefault(m => m.Email == Configuration["Email"]);
var Role = Context.Roles.SingleOrDefault(m => m.Name == Configuration["Role"]);
IdentityUserRole<string> UserRole = new IdentityUserRole<string>() { UserId = Admin.Id, RoleId = Role.Id };
Context.UserRoles.Add(UserRole);
Context.SaveChanges();
}
Everything runs perfect except I can't seed the UserRole DB with Data. From DBContext I add IdentityUserRole entity and save the changes to DB. Although nothing passed under the DB. Any suggestion?
Create a class named StartupDbInitializer:
using System;
using System.Collections.Generic;
using System.Linq;
using Core.Entities;
using Microsoft.AspNetCore.Identity;
namespace Core.Startups
{
public class StartupDbInitializer
{
private const string AdminEmail = "admin#admin.com";
private const string AdminPassword = "StrongPasswordAdmin123!";
private static readonly List<IdentityRole> Roles = new List<IdentityRole>()
{
new IdentityRole {Name = "Admin", NormalizedName = "ADMIN", ConcurrencyStamp = Guid.NewGuid().ToString()}
};
public static void SeedData(ApplicationDbContext dbContext, UserManager<User> userManager)
{
dbContext.Database.EnsureCreated();
AddRoles(dbContext);
AddUser(dbContext, userManager);
AddUserRoles(dbContext, userManager);
}
private static void AddRoles(ApplicationDbContext dbContext)
{
if (!dbContext.Roles.Any())
{
foreach (var role in Roles)
{
dbContext.Roles.Add(role);
dbContext.SaveChanges();
}
}
}
private static async void AddUser(ApplicationDbContext dbContext, UserManager<User> userManager)
{
if (!dbContext.Users.Any())
{
var user = new User {
UserName = AdminEmail,
Email = AdminEmail,
IsEnabled = true,
EmailConfirmed = true,
};
await userManager.CreateAsync(user, AdminPassword);
}
}
private static void AddUserRoles(ApplicationDbContext dbContext, UserManager<User> userManager)
{
if (!dbContext.UserRoles.Any())
{
var userRole = new IdentityUserRole<string>
{
UserId = dbContext.Users.Single(r => r.Email == AdminEmail).Id,
RoleId = dbContext.Roles.Single(r => r.Name == "Admin").Id
};
dbContext.UserRoles.Add(userRole);
dbContext.SaveChanges();
}
}
}
}
Then call it in your Startup's Configure method:
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ApplicationDbContext dbContext,
UserManager<User> userManager,
)
{
// rest of code...
StartupDbInitializer.SeedData(dbContext, userManager);
}
Above, I inject my DbContext and UserManager<T>.
Try this line... it must work.
ApplicationUser user = await _usermanager.FindByEmailAsync("your.email#mymail.com");
if (!await _usermanager.IsInRoleAsync(user, "Admin"))
{
await _usermanager.AddToRoleAsync(user, "Admin");
}
When you tried it and it works, change it to your config parameters if you prefer them. It's not that hard to get it to work, you have everything you need in UserManager and RoleManager classes.
I still say you have to check if the role exist in table before you insert it, I got all my roles populated every time I run the application before I added the check.
if ((await _roleManager.FindByNameAsync("Admin")) == null)
{
await _roleManager.CreateAsync(new IdentityRole { Name = "Admin" });
}

date filtering not working in smart gwt

i am developing a smartGWt application that needs to filter list grid content by date and by other staff, every thing is working correctly except the date filtration, this is how i am defining the date fields :
registeredDate = new DataSourceDateField("registrationDate", voc.registeredDate());
registeredDate.setRequired(true);
verificationDate = new DataSourceDateField("lastVerificationDate", voc.verificationDate());
verificationDate.setRequired(true);
the same as every other field
this is how i fill records :
registeredUsersRecords = new ListGridRecord[registeredUsers.length()];
ListGridRecord record = new ListGridRecord();
record.setAttribute(ID, user.getId());
record.setAttribute("firstName", user.getFirstName());
record.setAttribute("lastName", user.getLastName());
record.setAttribute("email", user.getEmail());
record.setAttribute("userMainType", type);
record.setAttribute("isActivated", (user.isActivated())? voc.active(): voc.inActive());
record.setAttribute("country", user.getSelectedCountry().getValue());
record.setAttribute("companyName", user.getCompanyName());
record.setAttribute("registrationDate", user.getRegistrationDate());
record.setAttribute("lastVerificationDate", user.getVerificationDate());
registeredUsersRecords[i] = record;
and then i put them into datasource :
DataSource ds = new DataSource();
ds.setClientOnly(true);
ds.setFields(fName, lName, email, type,typeDetails, status, country, companyName, registeredDate,verificationDate);
for(int i = 0; i< registeredUsersRecords.length; i++){
ds.addData(registeredUsersRecords[i]);
}
registeredUsersListGrid.setDataSource(ds);
registeredUsersListGrid.fetchData();
You have not shared a complete code.
Still I am trying to provide you a sample code. Please have a look.
public class SmartGWTProject implements EntryPoint {
public void onModuleLoad() {
class User {
private int id;
private String firstName;
private Date registrationDate;
public User(int id, String firstName, Date registrationDate) {
this.id = id;
this.firstName = firstName;
this.registrationDate = registrationDate;
}
public int getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public Date getRegistrationDate() {
return registrationDate;
}
}
DateTimeFormat format = DateTimeFormat.getFormat("MM/dd/yyyy");
User[] registeredUsers = new User[] { new User(1, "a", format.parse("01/20/2014")),
new User(2, "b", format.parse("05/20/2013")),
new User(3, "c", format.parse("02/20/2014")) };
ListGridRecord[] registeredUsersRecords = new ListGridRecord[registeredUsers.length];
for (int i = 0; i < registeredUsers.length; i++) {
User user = registeredUsers[i];
ListGridRecord record = new ListGridRecord();
record.setAttribute("id", user.getId());
record.setAttribute("firstName", user.getFirstName());
record.setAttribute("registrationDate", user.getRegistrationDate());
registeredUsersRecords[i] = record;
}
DataSourceDateField registeredDate = new DataSourceDateField("registrationDate", "Date");
DataSourceTextField firstName = new DataSourceTextField("firstName", "Name");
DataSourceIntegerField id = new DataSourceIntegerField("id", "ID");
id.setRequired(true);
id.setPrimaryKey(true);
id.setHidden(true);
DataSource ds = new DataSource();
ds.setClientOnly(true);
ds.setFields(id, firstName, registeredDate);
for (int i = 0; i < registeredUsersRecords.length; i++) {
ds.addData(registeredUsersRecords[i]);
}
ListGrid registeredUsersListGrid = new ListGrid();
registeredUsersListGrid.setDataSource(ds);
registeredUsersListGrid.fetchData();
registeredUsersListGrid.draw();
}
}

How to retrieve all the Groups/Roles a user is member of using SOAP services?

I am trying to collect some user informations using SOAP services.
I was able to get the Job Title for a given user, but I don't understand how to retrieve the list of groups and roles that a user has.
Can I simply use the GroupServiceSoap.getUserPlaces(long userId, String[] classNames, int max) method? Or is there another way I can get these fields?
Currently my code:
private static URL _getURL(String remoteUser, String password, String serviceName) {
final String LIFERAY_PROTOCOL = "http://";
final String LIFERAY_TCP_PORT = "8080";
final String LIFERAY_FQDN = "localhost";
final String LIFERAY_AXIS_PATH = "/api/secure/axis/";
try {
return new URL(LIFERAY_PROTOCOL + URLEncoder.encode(remoteUser, "UTF-8") + ":"
+ URLEncoder.encode(password, "UTF-8") + "#" + LIFERAY_FQDN
+ ":" + LIFERAY_TCP_PORT + LIFERAY_AXIS_PATH + serviceName);
} catch (MalformedURLException e) {
return null;
} catch (UnsupportedEncodingException e) {
return null;
}
}
[...]
public static void main(String[] argv){
public final String LIFERAY_USER_SERVICE="Portal_UserService";
public final String LIFERAY_COMPANY_SERVICE="Portal_CompanyService";
public final String LIFERAY_GROUP_SERVICE = "Portal_GroupService";
//company.default.web.id property
public final String LIFERAY_DEFAULT_COMPANY_ID = "liferay.com";
UserServiceSoap userService = new UserServiceSoapServiceLocator().getPortal_UserService(_getURL(USER_IDENTIFIER,USER_PASSWORD, LIFERAY_USER_SERVICE));
//This code is usefull if you want to use SOAP setter.
//((Portal_UserServiceSoapBindingStub) userService).setUsername(USER_IDENTIFIER);
//((Portal_UserServiceSoapBindingStub) userService).setPassword(USER_PASSWORD);
CompanyServiceSoap companyService = new CompanyServiceSoapServiceLocator().getPortal_CompanyService(_getURL(USER_IDENTIFIER, USER_PASSWORD, LIFERAY_COMPANY_SERVICE));
long companyId = companyService.getCompanyByMx(LIFERAY_DEFAULT_COMPANY_ID).getCompanyId();
// Here I retrieve my user, and can access some properties, but not them all !
UserSoap user = userService.getUserByEmailAddress(companyId, target_user_mail);
//TODO : I got hte JobTittle that I want, later I will do something more util thant just print it, I swear it my precious !
System.out.println(user.getJobTitle());
GroupServiceSoap groupService = new GroupServiceSoapServiceLocator().getPortal_GroupService(_getURL(USER_IDENTIFIER, USER_PASSWORD, LIFERAY_GROUP_SERVICE));
//this one return an empty array
GroupSoap[] userPlaces = groupService.getUserPlaces(new String[]{"Group", "Role"}, 150);
//this return an array of size 1, but the only GroupSoap seems to be a structural groups without any usefull properties to me.
GroupSoap[] userPlaces = groupService.getUserPlaces(null, 150);
}
Use this method to get user role and group user id
UserServiceSoap.getRoleUserIds
UserServiceSoap.getGroupUserIds
HTH
It is only a partial answer.
In order to get all the User Roles one can do this :
RoleServiceSoap roleService = new RoleServiceSoapServiceLocator().getPortal_RoleService(_getURL(USER_IDENTIFIER, USER_PASSWORD, LIFERAY_ROLE_SERVICE));
RoleSoap[] userRoles = roleService.getUserRoles(user.getUserId());
with user variable an instance of UserSoap.
The SOAP access must be done by an Admin user in order to get access to the Role List. The user can't access this himself.