#Transactional(propagation = Propagation.REQUIRED) not working in Threading - multithreading

I have created manual transaction it works but when using transaction annotation it fails by giving below error
Error :
could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
Error
com.krawler.common.service.ServiceException: system failure: getJournalEntryJson : could not initialize proxy - no Session
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
Code structure
Controller Class {
ModelAndView
export {
thread call(JounralExport)
}
}
JounralExport {
void run() {
Function1();
Function2();
Function3();
}
Function1() {
manual transaction create commit;
}
Function2() {
FucntionA();
}
Function3() {
manual transaction create commit;
}
}
Class B {
#Transactional(propagation = Propagation.REQUIRED) private JounralExport entry;
setter FuncitonA() {
obj.put("companyname", entry.getCompany().getCompanyName()); // error could not initialize proxy - no Session
}
}

Related

How to abort a Task in JavaFX?

Is it possible to abort a Task in JavaFX? My Task could run into situations where I want to cancel the rest of the operations within it.
I would need to return a value, somehow, so I can handle the cause of the abort in the JFX Application Thread.
Most of the related answers I've seen refer to handling an already-canceled Task, but now how to manually cancel it from within the Task itself.
The cancel() method seems to have no effect as both messages below are displayed:
public class LoadingTask<Void> extends Task {
#Override
protected Object call() throws Exception {
Connection connection;
// ** Connect to server ** //
updateMessage("Contacting server ...");
try {
connection = DataFiles.getConnection();
} catch (SQLException ex) {
updateMessage("ERROR: " + ex.getMessage());
ex.printStackTrace();
cancel();
return null;
}
// ** Check user access ** //
updateMessage("Verifying user access ...");
try {
String username = System.getProperty("user.name");
ResultSet resultSet = connection.createStatement().executeQuery(
SqlQueries.SELECT_USER.replace("%USERNAME%", username));
// If user doesn't exist, block access
if (!resultSet.next()) {
}
} catch (SQLException ex) {
}
return null;
}
}
And example would be greatly appreciated.
Why not just let the task go into a FAILED state if it fails? All you need (I also corrected the errors with the type of the task and return type of the call method) is
public class LoadingTask extends Task<Void> {
#Override
protected Void call() throws Exception {
Connection connection;
// ** Connect to server ** //
updateMessage("Contacting server ...");
connection = DataFiles.getConnection();
// ** Check user access ** //
updateMessage("Verifying user access ...");
String username = System.getProperty("user.name");
ResultSet resultSet = connection.createStatement().executeQuery(
SqlQueries.SELECT_USER.replace("%USERNAME%", username));
// I am not at all sure what this is supposed to do....
// If user doesn't exist, block access
if (!resultSet.next()) {
}
return null;
}
}
Now if an exception is thrown by DataFiles.getConnection(), the call method terminates immediately with an exception (the remained is not executed) and the task enters a FAILED state. If you need access to the exception in the case that something goes wrong, you can do:
LoadingTask loadingTask = new LoadingTask();
loadingTask.setOnFailed(e -> {
Throwable exc = loadingTask.getException();
// do whatever you need with exc, e.g. log it, inform user, etc
});
loadingTask.setOnSucceeded(e -> {
// whatever you need to do when the user logs in...
});
myExecutor.execute(loadingTask);

Test Method Implementation in jhipster

I need to implement a test method to cover the following method. But it is not compulsory to cover it for 100% coverage.
#DeleteMapping("/users/{login:" + Constants.LOGIN_REGEX + "}")
#Timed
#Secured({AuthoritiesConstants.ADMIN, AuthoritiesConstants.STUDENT})
public ResponseEntity<Void> deleteUser(#PathVariable String login) {
log.debug("REST request to delete User: {}", login);
boolean hasAuthorityStudent = false;
boolean hasAuthorityAdmin = false;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
hasAuthorityAdmin = authorities.contains(new SimpleGrantedAuthority(AuthoritiesConstants.ADMIN));
hasAuthorityStudent = authorities.contains(new SimpleGrantedAuthority(AuthoritiesConstants.STUDENT));
if (hasAuthorityAdmin) {
// delete user
userService.deleteUser(login);
return ResponseEntity.ok().headers(HeaderUtil.createAlert("userManagement.deleted", login)).build();
} else {
//get the authorities of the user who is going to be deleted
Optional<User> user = userService.getUserWithAuthoritiesByLogin(login);
Set<Authority> currentUserAuthorities = user.get().getAuthorities();
log.debug("REST request to delete User: {}", user);
log.debug("REST request to delete Member: {}", currentUserAuthorities);
boolean hasDeletedMembByStu = false;
if (hasAuthorityStudent) {
for (Authority auth : currentUserAuthorities) {
// delete user if it is a student
if (auth.getName().equals(AuthoritiesConstants.MEMBER)) {
userService.deleteUser(login);
hasDeletedMembByStu = true;
}
}
if (hasDeletedMembByStu) {
return ResponseEntity.ok().headers(HeaderUtil.createAlert("userManagement.deleted", login)).build();
}
}
return ResponseEntity.badRequest()
.headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "AccessDenied", "Lecturer can delete only members"))
.body(null);
}
}
I an using 4.8.2 as the jhipster version. I have attempted as follows.
#Test
#Transactional
public void deleteUser() throws Exception {
// Initialize the database
userRepository.saveAndFlush(user);
userSearchRepository.save(user);
restUserMockMvc.perform(delete("/api/users/{login}", user.getLogin())
.contentType(TestUtil.APPLICATION_JSON_UTF8))
.andExpect(status().isBadRequest());
}
There user is initialized with ROLE_USER. Then generated a build failure of the test method saying java.lang.AssertionError: Status expected:<400> but was:<500&gt
You are not logged in so authentication is null and authentication.getAuthorities() throws a NullPointerException.
To fix that you need to apply Spring-Security like here and assign a user and roles to your request like here.
Other note : instead of calling SecurityContextHolder.getContext().getAuthentication() you can get the principal directly in the controller method :
ResponseEntity<Void> deleteUser(#PathVariable String login, Principal principal) {
log.debug("REST request to delete User: {}", login);
boolean hasAuthorityStudent = false;
boolean hasAuthorityAdmin = false;
if (principal != null) {
Collection<? extends GrantedAuthority> authorities = principal.getAuthorities();
...

Writing custom Shiro realm

I am constructing my own AuthorizingRealm subclass, and am having a tough time wiring it up to my SecurityManager.
The essence of my realm:
public class MyRealm extends AuthorizingRealm {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
try {
// My custom logic here
} catch(Throwable t) {
System.out.println(t.getMessage());
}
SimpleAuthenticationInfo authn = new SimpleAuthenticationInfo(new MyUser(), "somePassword");
return authn;
}
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
try {
// My custom logic here
} catch(Throwable t) {
System.out.println(t.getMessage());
}
return new SimpleAuthorizationInfo();
}
}
Then in my 'shiro.ini':
# =======================
# Shiro INI configuration
# =======================
[main]
myRealm = com.me.myapp.security.MyRealm
Then in my Driver class/main method (that I'm using for testing):
public class Driver {
public static void main(String[] args) {
Driver d = new Driver();
d.test();
}
public void test() {
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
UsernamePasswordToken token = new UsernamePasswordToken("", "");
token.setRememberMe(true);
System.out.println("Shiro props:");
System.out.println(securityManager.getProperties());
Subject currentUser = SecurityUtils.getSubject()
try {
currentUser.login(token)
println "I think this worked!"
} catch (UnknownAccountException uae) {
println "Exception: ${uae}"
} catch (IncorrectCredentialsException ice) {
println "Exception: ${ice}"
} catch (LockedAccountException lae) {
println "Exception: ${lae}"
} catch (ExcessiveAttemptsException eae) {
println "Exception: ${eae}"
} catch (AuthenticationException ae) {
println "Exception: ${ae}"
}
}
}
When I run this I get:
Shiro props:
[class:class org.apache.shiro.mgt.DefaultSecurityManager, cacheManager:null, subjectFactory:org.apache.shiro.mgt.DefaultSubjectFactory#6a2b8b42, authorizer:org.apache.shiro.authz.ModularRealmAuthorizer#50c3d082, realms:[com.me.myapp.security.MyRealm#67ae303a], subjectDAO:org.apache.shiro.mgt.DefaultSubjectDAO#5ce06503, rememberMeManager:null, authenticator:org.apache.shiro.authc.pam.ModularRealmAuthenticator#1007d798, sessionManager:org.apache.shiro.session.mgt.DefaultSessionManager#72db4460]
Exception: org.apache.shiro.authc.AuthenticationException: Authentication failed for token submission [org.apache.shiro.authc.UsernamePasswordToken - , rememberMe=true]. Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException).
So it looks like its reading my shiro.ini because its picking up the correct realm, but MyRealm doesn't do anything except stub out dummy users that should authenticated regardless of the username/password supplied. Any ideas as to where I'm going awry?
add this to your shiro.ini: securityManager.realms = $myRealm then in your Driver class
UsernamePasswordToken token = new UsernamePasswordToken("", "somePassword");
instead of an empty passowrd.
I think this worked!
I have not done this myself, but here are a couple of things you can try:
If you don't need authorization logic, consider subclassing AuthenticatingRealm instead of AuthorizingRealm
In method doGetAuthenticationInfo, consider using this code:
SimpleAuthenticationInfo authn = new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), "myRealm");
You seem to have created a Realm properly but have not told the SecurityManager that it is one the realms to be used. In that way, it is just another object created in the main section of shiro.ini.
To tell Shiro's SecurityManager that it needs to use myRealm as a Realm, you need to add this to your shiro.ini:
securityManager.realms = $myRealm

Custom exception handlers never called in ServiceStack 4

In ServiceStack 3 I had a custom handler decorating the result DTO in case of exceptions:
ServiceExceptionHandler = (request, exception) =>
{
var ret = DtoUtils.HandleException(this, request, exception);
var error = ret as HttpError;
if ( error == null )
return ret;
// ...
error.Response = new MyErrorResponse
{
ResponseStatus = responseStatus,
// ...
};
return ret;
};
After migrating to ServiceStack 4 I tried different hooks:
ServiceExceptionHandlers.Add
OnExceptionTypeFilter
Own ServiceRunner with overridden HandleException
Neither of them is been called when exceptions occur. What am I missing?
I'm using the new Task based services, if this is relevant.
Edit: A simple test service included in my solution triggers the hooks:
[Route("/test")]
public class TestRequest : IReturn<int>
{
}
public class TestService : Service
{
public Task<int> Get(TestRequest request)
{
throw new Exception("Ha!");
}
}
Edit2: Seems to be a bug in the handling of asynchronous services. If I move the exception from the synchronous to the asynchronous part of the handler, none of the hooks are called:
public class TestService : Service
{
public async Task<int> Get(TestRequest request)
{
await Task.Yield();
throw new Exception("Ha!");
}
}

ServiceExceptionHandler usage on RestServiceBase<T>

I'm trying to use the ServiceExceptionHandler on my Serivce which extends RestServiceBase<TViewModel>
I can use the AppHost.ServiceExceptionHandler, that's working fine. I need the user info from the HttpRequest, thats not available at AppHost level.
So I'm trying to use the ServiceExceptionHandler on Service level. Though I set the delegate on service ctor, it's null when exception thrown on OnGet method
public class StudentService : RestServiceBase<Student>
{
public StudentService()
{
ServiceExceptionHandler = (request, exception) =>
{
logger.Error(string.Format("{0} - {1} \n Request : {2}\n", HttpRequest.UserName(), exception.Message, request.Dump()), exception);
var errors = new ValidationErrorField[] { new ValidationErrorField("System Error", "TODO", "System Error") };
return DtoUtils.CreateErrorResponse("System Error", "System Error", errors);
};
}
}
I'm not sure of what is the issue with this code. Any help will be appreciated.
Register Global AppHost.ServiceExceptionHandler
In your AppHost.Configure() you can register a global Exception handler with:
this.ServiceExceptionHandler = (request, ex) => {
... //handle exception and generate your own ErrorResponse
};
For finer-grained Exception handlers you can override the following custom service event hooks:
Handling Exceptions with the New API
If you're using the New API you can override the Exception by providing a custom runner, e.g:
public class AppHost {
...
public virtual IServiceRunner<TRequest> CreateServiceRunner<TRequest>(
ActionContext actionContext)
{
//Cached per Service Action
return new ServiceRunner<TRequest>(this, actionContext);
}
}
public class MyServiceRunner<T> : ServiceRunner<T> {
public override object HandleException(
IRequestContext requestContext, TRequest request, Exception ex) {
// Called whenever an exception is thrown in your Services Action
}
}
Handling Exceptions with the Old API
RestServiceBase<T> is uses the old API in which you can handle errors by overriding the HandleException method, e.g:
public class StudentService : RestServiceBase<Student>
{
...
protected override object HandleException(T request, Exception ex)
{
LogException(ex);
return base.HandleException(request, ex);
}
}

Resources