Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • May 11 07:35

    xvik on master

    support providing config overri… (compare)

  • May 08 11:33

    xvik on master

    remove usages and mentions of d… disable signing for jitpack bui… (compare)

  • May 06 08:26

    dependabot[bot] on gradle

    (compare)

  • May 06 08:26

    xvik on master

    Bump spotbugs-annotations from … Merge pull request #225 from xv… (compare)

  • May 06 08:26
    xvik closed #225
  • May 06 00:20
    codecov-commenter commented #225
  • May 06 00:19
    codecov-commenter commented #225
  • May 05 23:12
    dependabot[bot] labeled #225
  • May 05 23:12
    dependabot[bot] opened #225
  • May 05 23:12

    dependabot[bot] on gradle

    Bump spotbugs-annotations from … (compare)

  • May 03 18:58

    xvik on gh-pages

    Publish 5.5.0 documentation (compare)

  • May 03 18:40

    dependabot[bot] on gradle

    (compare)

  • May 03 18:40
    dependabot[bot] commented #224
  • May 03 18:40
    xvik closed #224
  • May 03 18:37

    xvik on gh-pages

    Publish 5.5.0 documentation (compare)

  • May 03 12:15

    xvik on master

    update to dropwizard 2.1.0 (compare)

  • May 03 10:28

    xvik on master

    mention in doc duplicate module… (compare)

  • May 02 23:14
    dependabot[bot] labeled #224
  • May 02 23:14
    dependabot[bot] opened #224
  • May 02 23:14

    dependabot[bot] on gradle

    Bump dropwizard-dependencies fr… (compare)

Eddie Xie
@oeddyo
Dynamic features
        CredentialRequiredFeature    (c.k.restful.filter)       
        LoginRequiredFeature         (c.k.restful.filter)       

    Exception mappers
        IndexNotFoundException         IndexNotFoundExceptionMapper (c.k.r.exceptionmapper)
ERROR [2020-06-16 18:22:29,915] io.dropwizard.jersey.errors.LoggingExceptionMapper: Error handling a request: c6536299f686a565
! org.apache.lucene.index.IndexNotFoundException: index 7617868c-fb63-41b5-81e6-50290cdc903exx does not exist
! at com.kalasearch.restful.filter.CredentialRequiredFilter.filter(CredentialRequiredFilter.java:61)
! at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:108)
maybe I'm not registering it correctly?
    bootstrap.addBundle(GuiceBundle.builder()
        .extensions(IndexNotFoundExceptionMapper.class)
        .extensions(
            AccountResource.class,
            AppResource.class,
            IndexResource.class,
            DocResource.class,
            CredentialRequiredFeature.class,
            LoginRequiredFeature.class
        )
Eddie Xie
@oeddyo
ah I found it probably has something to do with the exception is thrown in the ContainerRequestFilter
if it's thrown elsewhere, the ExceptionMapper can actually catch it
Vyacheslav Rusakov
@xvik
hi @oeddyo ! Actually LoggingExceptionMapper (shown in error log) is the default dropwizard mapper, so mappers mechanism was used. It is better to debug exception handling to see why it choose default handler instead of your custom mapper. org.glassfish.jersey.internal.ExceptionMapperFactory#find(java.lang.Class<T>, T) - mapper selection logic
Eddie Xie
@oeddyo
@xvik looks like in the function you mentioned, it's trying to search for which is the most "suitable" exceptionMapper by looking at distance
Eddie Xie
@oeddyo
it's interesting... i didn't do anything new but now it seems be able to recognize the exp mapper :|
Eddie Xie
@oeddyo
hmm... it happened again. I'm throwing an exception in resource now, but for some reason the mapperFactory you mentioned keep finding the default mapper so my IndexNotFoundExceptionMapper is not used
image.png
Eddie Xie
@oeddyo
The code in resource is very simple. I'm testing if an indexId exists, if not throw this exception:
  public Index getIndex(@PathParam("indexId") String indexId) {
    Optional<Index> indexOpt = indexDao.findById(indexId);
    if (indexOpt.isPresent()) {
      return indexOpt.get();
    } else {
      throw new IndexNotFoundException(indexId);
    }
  }
exception mapper:

@Provider
public class IndexNotFoundExceptionMapper
    implements ExceptionMapper<IndexNotFoundException> {

  @Override
  public Response toResponse(IndexNotFoundException indexNotFoundException) {
    int errorCode = ErrorConstants.INDEX_NOT_FOUND_CODE;
    String errorMessage =
        String.format(
            ErrorConstants.INDEX_NOT_FOUND,
            indexNotFoundException.getIndexId()
        );

    return Response
        .status(Response.Status.NOT_FOUND)
        .entity(
            new KalaErrorEntity(
                errorMessage,
                errorCode
            )
        )
        .build();
  }
}
Eddie Xie
@oeddyo

  public void initialize(Bootstrap<HttpServerConfiguration> bootstrap) {
    // register hbn bundle before guice to make sure factory initialized before guice context start
    final HbnBundle hibernate = new HbnBundle();
    bootstrap.addBundle(hibernate);
    // do not use auto scan here otherwise filter will be scanned without CredentialRequiredFeature
    bootstrap.addBundle(GuiceBundle.builder()
        .extensions(
            AccountResource.class,
            AppResource.class,
            IndexResource.class,
            DocResource.class,
            CredentialRequiredFeature.class,
            LoginRequiredFeature.class,
            IndexNotFoundExceptionMapper.class,
            CredentialUnauthorizedExceptionMapper.class
        )
        .modules(new HbnModule(hibernate))
        .modules(new GuiceModule())
        .build());
  }
Tried so many things... doesn't seem to be working :(
Vyacheslav Rusakov
@xvik
@oeddyo don't know why it's not working.. it should. Only debug could reveal the reason. You can try to use ExtendedExceptionMapper: it has an addition method to implement which is always called during mapper search. Not much, just the way to be sure jersey is aware of your mapper (just don't use it).. but in this case also further debug will be required.
Eddie Xie
@oeddyo
I think jersey is aware of the mapper. When the mapperFactory.find is trying to find a proper mapper (by computing some sort of distance) I can see the defined mapper IndexNotFoundExceptionMapper there
is it possible this is caused by Guicey? to verify that I can register the mapper in run function of Application<HttpServerConfiguration> and without using extensions(IndexNotFoundExceptionMapper) but use environment.jersey().register(new CredentialUnauthorizedExceptionMapper()); instead right?
Eddie Xie
@oeddyo
got it! I didn't add the mapper in test case when I'm testing Resource.
  public ResourceExtension resourceExtension = ResourceExtension.builder()
      .addResource(
          new IndexResource(indexDao, indexServiceManager)
      )
      .addResource(new IndexNotFoundExceptionMapper())
      .build();
this works^
@xvik thanks a lot for the pointer!
Shachar Levy
@levyshachar2

Hi all , I have a question regarding the JDBI3 extension.

I'm trying to add to our solution a support for @UnitOfWork annotation with the JDBI extension.
Currently we use Guice to inject Resources and DAO's.
We have one ServiceModule and one DataAccessModule
in ServiceModule we do the following for all our Jeresy resources
binder.bind(FooResource.class);

And in our DataAccessModule
@Provides fun fooDao(dbi: Jdbi): FooDao = dbi.onDemand(FooDao::class.java)

and of all these are defined in the Init function in the server
guiceBundle = GuiceBundle.builder() .modules(ServiceModule, DataAccessModule...) .build();

This code above works , however once ill change it to

 `guiceBundle = GuiceBundle.builder()
      .bundles(JdbiBundle.<Configucation>forDatabase((conf, env) -> conf.getDataSourceFactory()))
      .modules(ServiceModule)
      .build();`

(notice I removed the DataAccessModule as I marked my DAO's with @JDBIRepository annotations so the repositoryInstaller should install them.

Now as you can see I added the JdbiBundle as per the documentation, but I'm getting a lot of Guice exceptions such as
1) No implementation for ..fooDAO was bound.
while locating .FooDao
for the 3rd parameter of fooHandler.<init>(FooHandler.kt:21)

Basically it looks like the resources are getting fired up before the DAO's in Guice , which causing him to throw exceptions as he don't have yet their mappings.

I added some debug information to Guicey and saw the following order of modules

    ServiceModule                (c.n.claims.di)            
           ...
    JdbiModule                   (r.v.g.jdbi3.module)       
    GuiceBootstrapModule         (r.v.d.guice.module)       

Can anyone give me some pointers on what am I doing wrong?

Thanks

Vyacheslav Rusakov
@xvik
@levyshachar2 hi! Classpath scan is not enabled and so guicey is not aware of your DAO's and did not bound them correctly. When guice started he see that DAO dependency is an abstract class and tries to find implementation binding which is not registered.
So eather enable auto config (.enableAutoConfig(package)) on guice bundle to automate extensions search (like in JDBI example) or declare you dao extensions manually: .extensions(MyDAO1.class, MyDAO2.class ).
Also, when dao extensions properly installed you should see all of them in the logs (actually, all used extensions are logged):
INFO  [2020-07-09 01:12:36,980] ru.vyarus.guicey.jdbi3.installer.repository.RepositoryInstaller: repositories = 

    (ru.vyarus.guicey.jdbi3.support.repository.CustTxRepository)
    (ru.vyarus.guicey.jdbi3.support.repository.LogicfulRepository)
    (ru.vyarus.guicey.jdbi3.support.repository.SampleRepository)
Shachar Levy
@levyshachar2

@xvik first, let me say thank you for your help.
I managed to get my service working ( I added manual bindings with the extensions you suggested)

However I'm facing now another issue
I'm getting the following errors:
Error handling a request: XXX! java.lang.IllegalStateException: Unit of work not started yet

It appears to happen when I try to invoke a function from my DAO injection.

For example I have in my handler constructor @Inject private val fooDao: FooDao

and then I do something like fooDao.insertFoo(foo:Foo)

not sure why I'm getting this error

Shachar Levy
@levyshachar2
I just see in the documentation that
"Don't use JDBI @Transaction and @CreateSqlObject annotations anymore: probably they will even work, but they are not needed now and may confuse.
I'll try to remove the @Transaction annotation
Vyacheslav Rusakov
@xvik
You will need to use guicey @InTransaction annotation instead of it (to declare unit of work scope).
Shachar Levy
@levyshachar2
It seems I still get the error even when I don't call the transaction
Simple get DAO call

fun getFooById(fooId: String): FooDto { val foo = fooDao.getFooByFooId(fooId) return foo.toDto() }

this is my function , where fooDAO is getting injected in the constructor
I'm still getting the error Unit of work not started yet

my fooDao is defined as

@JdbiRepository interface fooDAO { }

Vyacheslav Rusakov
@xvik
@levyshachar2 problem may be caused by kotlin: by default it makes all methods final and so guice could not apply AOP on them (transaction support is AOP based). It's easy to check: use aop diagnostic report to see if your method (or dao calling method, depends on where you put InTransaction annotation) is handled with aop
Shachar Levy
@levyshachar2
But i'm not using the InTransaction annotation in this function at all , do I need to add the open key anyway for that function?
Vyacheslav Rusakov
@xvik
The error telling that you're calling your dao method not withing unit of work
Shachar Levy
@levyshachar2
I don't need transaction in that function , as it just a simple get
Vyacheslav Rusakov
@xvik
Unit of work may be automatic with InTransaction annotation: in this case you need to annotate called dao method or any method calling this method
or you can declare unit of work manually
in any case your dao methods must be called within unit of work
Usually I put InTransaction directly on dao interfaces declaring the smallest unit of work (dao method call will not fail in any case)
Shachar Levy
@levyshachar2
so basically every function in my DAO should be in some transaction , either with the InTransaction annotation or manually?
Vyacheslav Rusakov
@xvik
Yes, unit of work == transaction (just dropwizard use this term for hibernate so I used it too in this module to unify meaning)
Shachar Levy
@levyshachar2

ok , so if I want to do a transaction of two DAO function calls , I will have another @InTransaction annotation for the function

@InTransaction
fun fooAndGoo() { fooDao.DoSomething() gooDao.doSomething() }

?

Vyacheslav Rusakov
@xvik
Annotation declares scope: annoting method means transaction scope will equal to this method. You can call any (number) of dao methods within this method and they would be called at the same transaction
if you put InTransaction at the class level it would affect all methods. So when I annotate DAO interface I declare minimal transaction scope (any called method would create its own transaction)
Shachar Levy
@levyshachar2
Got it , thank you!
Vyacheslav Rusakov
@xvik
If you have some annotated service method which calls muliple dao methods then you enlarge transaction scope (annotation on dao interface ignored in this case and all methods will be called at the same transaction)
Shachar Levy
@levyshachar2
so basically the top layer annotation defined the daos for all the transaction
Vyacheslav Rusakov
@xvik
top layer annotation defines actual transaction scope other scope declarations inside it are ignored (as scope already opened)