Genesys Backend issueshttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues2019-01-07T18:24:00+01:00https://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/398Fix: KPI List of available metrics2019-01-07T18:24:00+01:00Matija ObrezaFix: KPI List of available metricsImplementation of `KPIServiceImpl#listExecutions` returns Executions where user has direct READ permission assigned.
Change this to `List<Execution>` with `@PostFilter("hasPermission(returnObject, ...`
# List of available metrics
**GE...Implementation of `KPIServiceImpl#listExecutions` returns Executions where user has direct READ permission assigned.
Change this to `List<Execution>` with `@PostFilter("hasPermission(returnObject, ...`
# List of available metrics
**GET** _/api/v1/kpi/observations_ returns the list of **names** of available metrics:
```json
[ "accession.updates","accessions.count","accessions.doi","dataset.accessions","institute.pdci"... ]
```2.4Matija ObrezaMatija Obrezahttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/399Accession with RepositoryFolder2019-01-15T11:26:44+01:00Matija ObrezaAccession with RepositoryFolderWe currently store accession-related images and files in the file repository at a specific path `/wiews/${instCode}/acn/${acceNumb}`. When loading full accession information, we check if such folder exists (by convention). This makes it ...We currently store accession-related images and files in the file repository at a specific path `/wiews/${instCode}/acn/${acceNumb}`. When loading full accession information, we check if such folder exists (by convention). This makes it difficult when ACCENUMB contains `/`.
Update `AccessionId` and add properties:
- `private RepositoryFolder repositoryFolder;`
- `private int imageCount;`
The `GenesysImageGalleryAspects` needs to be extended and the `repositoryFolder` (of the `ImageGallery`) recorded with the `Accession`. The `imageCount` in the `AccessionId` should be updated after each image `save` or `delete` in the accession's image gallery.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/400Remove AuditedModel class2019-01-11T18:28:58+01:00Matija ObrezaRemove AuditedModel classUpgrade entities that extend `AuditedModel` (`Article`, `ITPGRFAStatus`, `Organization`, `VerificationToken`) to use `AuditedVersionedModel`.
Remove `AuditedModel` from the code.
Update liquibase.Upgrade entities that extend `AuditedModel` (`Article`, `ITPGRFAStatus`, `Organization`, `VerificationToken`) to use `AuditedVersionedModel`.
Remove `AuditedModel` from the code.
Update liquibase.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/401Download MCPD for subsets and datasets2019-01-17T21:06:59+01:00Matija ObrezaDownload MCPD for subsets and datasetsAdd API endpoints to generate and stream Excel with MCPD passport data for any:
- subset
- dataset
Add buttons to UI.Add API endpoints to generate and stream Excel with MCPD passport data for any:
- subset
- dataset
Add buttons to UI.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/402Filter by WorldClim data2019-01-17T16:44:30+01:00Matija ObrezaFilter by WorldClim dataIntroduce a new `WorldClim` model with type `Double` properties: ***tileIndex* as primary key** `+ private Double ` *alt tmin1 tmax1 tmean1 prec1 tmin2 tmax2 tmean2 prec2 tmin3 tmax3 tmean3 prec3 tmin4 tmax4 tmean4 prec4 tmin5 tmax5 tmea...Introduce a new `WorldClim` model with type `Double` properties: ***tileIndex* as primary key** `+ private Double ` *alt tmin1 tmax1 tmean1 prec1 tmin2 tmax2 tmean2 prec2 tmin3 tmax3 tmean3 prec3 tmin4 tmax4 tmean4 prec4 tmin5 tmax5 tmean5 prec5 tmin6 tmax6 tmean6 prec6 tmin7 tmax7 tmean7 prec7 tmin8 tmax8 tmean8 prec8 tmin9 tmax9 tmean9 prec9 tmin10 tmax10 tmean10 prec10 tmin11 tmax11 tmean11 prec11 tmin12 tmax12 tmean12 prec12 bio1 bio2 bio3 bio4 bio5 bio6 bio7 bio8 bio9 bio10 bio11 bio12 bio13 bio14 bio15*.
Variable names are explained at http://worldclim.org/bioclim and http://worldclim.org/formats1 -- we need this for the UI.
All properties need their own database index.
Introduce a `WorldclimService` and `*Repository` as needed.
Update the `WorldclimUpdater` to update the new entity, not the DS2 dataset.
~~http://localhost:8080/admin/ds2/ -- update WC, then migrate current `DS2` **worldclim.org** dataset to the new model -- MVC admin action only.~~
Add `private Worldclim climate` to `AccessionGeo`, it should use the `accessionGeo#tileIndex` to link to the corresponding `WorldClim` entity. This will include the climate data in the Elasticsearch index and enable "Overviews" to work.
Implement a new filter `WorldclimFilter` with `NumberFilter` for all variables in `WorldClim` model. Add `public WorldclimFilter climate` to `AccessionFilter` to allow filtering by climatic properties.
Update `WorldclimUpdater` to use WorldClim 2.0 at http://worldclim.org/version2
2.4Matija ObrezaMatija Obrezahttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/404Frontend URL2019-01-27T17:19:18+01:00Matija ObrezaFrontend URLThe server "public URL" is configured in `.properties`:
```
host.name=localhost
host.nameAndPort=${host.name}
base.url=http://${host.name}:8080
```
and these values are used as the base url in emails, redirects, sitemap controller, etc...The server "public URL" is configured in `.properties`:
```
host.name=localhost
host.nameAndPort=${host.name}
base.url=http://${host.name}:8080
```
and these values are used as the base url in emails, redirects, sitemap controller, etc. With the new website, we need another setting `frontend.url` where we can configure the URL to be used.
```
frontend.url=http://localhost:3000
```
Find references to `base.url` in code and replace with `frontend.url` as appropriate.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/405Transaction boundaries2019-01-22T13:35:13+01:00Matija ObrezaTransaction boundariesWe're doing something wrong either in the AuditLog or in the AccessionProcessor. It may have something to do with `REQUIRES_NEW` which will conflict with inserting audit logs (at level 1):
```java
@Override
public void beforeTransacti...We're doing something wrong either in the AuditLog or in the AccessionProcessor. It may have something to do with `REQUIRES_NEW` which will conflict with inserting audit logs (at level 1):
```java
@Override
public void beforeTransactionCompletion(final Transaction tx) {
if (level == 1 && auditLogs.get().size() > 0) {
LOG.trace("We have {} auditlogs", auditLogs.get().size());
auditLogs.get().stream().forEach(auditLog -> {
LOG.debug("Audit log to save: {}", auditLog);
});
this.auditTrailService.addAuditLogs(auditLogs.get());
auditLogs.get().clear();
}
super.beforeTransactionCompletion(tx);
}
```
I guess we need to add level-specific `auditLogs` lists.
```
13:24:19,215 genesys-background-2 DEBUG o.g.s.m.a.AdminController:366 - Assigned 654 tileIndexes
13:24:20,302 qtp147403080-32 INFO o.g.s.s.w.AccessionProcessor:198 - Processing Accessions took 4088907ms
13:24:20,335 qtp147403080-32 ERROR o.h.i.SessionImpl:521 - HHH000088: Exception in interceptor beforeTransactionCompletion()
org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:333)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:525)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:209)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy340.save(Unknown Source)
at sun.reflect.GeneratedMethodAccessor575.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy341.save(Unknown Source)
at org.genesys.blocks.auditlog.service.impl.AuditTrailServiceImpl.addAuditLogs(AuditTrailServiceImpl.java:75)
at sun.reflect.GeneratedMethodAccessor585.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy342.addAuditLogs(Unknown Source)
at org.genesys.blocks.auditlog.component.AuditTrailInterceptor.beforeTransactionCompletion(AuditTrailInterceptor.java:719)
at org.genesys2.spring.config.DatabaseConfig$1.beforeTransactionCompletion(DatabaseConfig.java:214)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:518)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:105)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:765)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:734)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:518)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
at org.genesys2.server.service.worker.AccessionProcessor$$EnhancerBySpringCGLIB$$7a6edb7c.apply(<generated>)
at org.genesys2.server.mvc.admin.AdminController.updateTileIndex(AdminController.java:348)
at org.genesys2.server.mvc.admin.AdminController$$FastClassBySpringCGLIB$$958b96d7.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
at org.genesys2.server.mvc.admin.AdminController$$EnhancerBySpringCGLIB$$183bd5b0.updateTileIndex(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:865)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1655)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:215)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.bufferAndPostProcess(ContentBufferingFilter.java:169)
at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.doFilter(ContentBufferingFilter.java:126)
at org.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:120)
at org.sitemesh.config.ConfigurableSiteMeshFilter.doFilter(ConfigurableSiteMeshFilter.java:163)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at org.genesys2.server.servlet.filter.LocaleURLFilter.doFilter(LocaleURLFilter.java:179)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at com.hazelcast.web.WebFilter.doFilter(WebFilter.java:293)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176)
at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145)
at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:389)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1634)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1340)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1242)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:503)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.exception.GenericJDBCException: could not execute statement
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211)
at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3032)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3558)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:98)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:492)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:197)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:181)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:216)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:334)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:289)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
at sun.reflect.GeneratedMethodAccessor582.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:300)
at com.sun.proxy.$Proxy208.persist(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:508)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:542)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:74)
at sun.reflect.GeneratedMethodAccessor576.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:515)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:500)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:477)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 171 more
Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:965)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:898)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:887)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:861)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2044)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2013)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5104)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1998)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
... 214 more
13:24:20,345 qtp147403080-32 WARN o.g.s.m.a.AdminController:370 - Done recalculating tileIndexes
```2.4Matija ObrezaMatija Obrezahttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/406Audited Subset2019-01-24T15:04:13+01:00Matija ObrezaAudited SubsetMake `Subset` an audited entity.Make `Subset` an audited entity.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/407RequestRejectedException logging2019-01-31T12:07:34+01:00Matija ObrezaRequestRejectedException loggingAdd `RequestRejectedException` to `UserControllerAdvice` as `@ResponseStatus(HttpStatus.BAD_REQUEST)`.
Our logs are filling up with log entires on invalid requests like `/zh%20https://dx.doi.org/10.18730/J69RS`:
```
2019-01-22T21:44:49...Add `RequestRejectedException` to `UserControllerAdvice` as `@ResponseStatus(HttpStatus.BAD_REQUEST)`.
Our logs are filling up with log entires on invalid requests like `/zh%20https://dx.doi.org/10.18730/J69RS`:
```
2019-01-22T21:44:49.178472275Z 2019-01-22 21:44:49.174:WARN:oejs.HttpChannel:qtp2027961269-136: /zh%20https://dx.doi.org/10.18730/J69RS
2019-01-22T21:44:49.178523532Z org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL was not normalized.
2019-01-22T21:44:49.178536170Z at org.springframework.security.web.firewall.StrictHttpFirewall.getFirewalledRequest(StrictHttpFirewall.java:123)
2019-01-22T21:44:49.178544339Z at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:193)
2019-01-22T21:44:49.178552584Z at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
2019-01-22T21:44:49.178559971Z at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
2019-01-22T21:44:49.178566143Z at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
2019-01-22T21:44:49.178572666Z at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
2019-01-22T21:44:49.178578859Z at org.genesys2.server.servlet.filter.LocaleURLFilter.doFilter(LocaleURLFilter.java:179)
2019-01-22T21:44:49.178585336Z at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
2019-01-22T21:44:49.178592151Z at com.hazelcast.web.WebFilter.doFilter(WebFilter.java:293)
2019-01-22T21:44:49.178598490Z at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
2019-01-22T21:44:49.178604983Z at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
2019-01-22T21:44:49.178613303Z at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
2019-01-22T21:44:49.178620417Z at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
2019-01-22T21:44:49.178627557Z at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
2019-01-22T21:44:49.178633984Z at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
2019-01-22T21:44:49.178640652Z at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176)
```2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/408KPI ExecutionRun totalValue2019-01-29T00:31:52+01:00Matija ObrezaKPI ExecutionRun totalValueAdd `private Double totalValue` to KPI `ExecutionRun` and fill it with the sum of all `observations.value` in `@PrePersist void prepersist() {}`.
Update liquibase:
- add column
- add SQL to fill `totalValue` with current sums for every...Add `private Double totalValue` to KPI `ExecutionRun` and fill it with the sum of all `observations.value` in `@PrePersist void prepersist() {}`.
Update liquibase:
- add column
- add SQL to fill `totalValue` with current sums for every execution run2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/409ClimateDataController v12019-01-29T18:26:31+01:00Matija ObrezaClimateDataController v1Add a new `ClimateDataController` in API *v1* namespace at */api/v1/climate* as base URL, with the following methods:
```java
@GetMapping("/current/{latitude},{longitude}")
public TileClimate getCurrentClimate(@PathVariable("latitude") ...Add a new `ClimateDataController` in API *v1* namespace at */api/v1/climate* as base URL, with the following methods:
```java
@GetMapping("/current/{latitude},{longitude}")
public TileClimate getCurrentClimate(@PathVariable("latitude") double latitude, double longitude) {
Long tileIndex = WorldClimUtil.getWorldclim25Tile(longitude, latitude);
if (tileIndex == null) {
throw new NotFoundElement("No current climate data for specified (lat, lon)");
}
return climateDataService.climateForTile(tileIndex);
}
@GetMapping("/past/{latitude},{longitude}")
public TileClimate getPastClimate(@PathVariable("latitude") double latitude, double longitude) {
throw new NotFoundElement("Past climate data not available");
}
@GetMapping("/future/{latitude},{longitude}")
public TileClimate getPastClimate(@PathVariable("latitude") double latitude, double longitude) {
throw new NotFoundElement("Future climate data not available");
}
```2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/411Bug: StartsWithFilter cannot be cast2019-02-01T08:21:26+01:00Matija ObrezaBug: StartsWithFilter cannot be castWhat's with `StartsWithFilter` cannot be cast to `LiteralValueFilter` in our converter?
```
Caused by: java.lang.ClassCastException: org.genesys2.server.service.impl.FilterHandler$StartsWithFilter cannot be cast to org.genesys2.server.s...What's with `StartsWithFilter` cannot be cast to `LiteralValueFilter` in our converter?
```
Caused by: java.lang.ClassCastException: org.genesys2.server.service.impl.FilterHandler$StartsWithFilter cannot be cast to org.genesys2.server.service.impl.FilterHandler$LiteralValueFilter
at org.genesys2.server.service.filter.AppliedFiltersConverter.take1String(AppliedFiltersConverter.java:258)
at org.genesys2.server.service.filter.AppliedFiltersConverter.apply(AppliedFiltersConverter.java:195)
at org.genesys2.server.service.filter.AppliedFiltersConverter.convert(AppliedFiltersConverter.java:179)
at org.genesys2.server.service.impl.FilterHandler$AppliedFilters.convert(FilterHandler.java:515)
```
Throw `InvalidApiUsageException` (extends RuntimeException) in:
```
21:25:39,611 qtp2027961269-15 ERROR o.g.s.m.UserControllerAdvice:103 - Could not convert filters on GET http://www.genesys-pgr.org/es/explore
java.lang.RuntimeException: Could not convert filters
at org.genesys2.server.service.impl.FilterHandler$AppliedFilters.convert(FilterHandler.java:517)
at org.genesys2.server.mvc.ExplorerController.viewFiltered(ExplorerController.java:240)
at org.genesys2.server.mvc.ExplorerController$$FastClassBySpringCGLIB$$827bbdf0.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:667)
at org.genesys2.server.mvc.ExplorerController$$EnhancerBySpringCGLIB$$590345b8.viewFiltered(<generated>)
```
also
```
Caused by: java.lang.RuntimeException: Unhandled Accession filter property=doi
at org.genesys2.server.service.filter.AppliedFiltersConverter.apply(AppliedFiltersConverter.java:252)
at org.genesys2.server.service.filter.AppliedFiltersConverter.convert(AppliedFiltersConverter.java:179)
at org.genesys2.server.service.impl.FilterHandler$AppliedFilters.convert(FilterHandler.java:515)
... 117 more
```2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/412Scheduled GLIS update2019-02-07T14:32:32+01:00Matija ObrezaScheduled GLIS updateAdd a scheduled task that runs on **1** cluster node every 6 hours and updates GLIS with `addtarget` with new accessions **with DOI** that were modified in the last **8 hours**.
Use code from `glisUpdater` in `AccessionListenersConfig` ...Add a scheduled task that runs on **1** cluster node every 6 hours and updates GLIS with `addtarget` with new accessions **with DOI** that were modified in the last **8 hours**.
Use code from `glisUpdater` in `AccessionListenersConfig` and remove that listener from `AccessionListenersConfig`.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/414Apache Mina logging2019-02-08T14:24:47+01:00Matija ObrezaApache Mina loggingPlease explore how we can reduce the verbosity of apache mina (FTP). The logs are filling up with:
```
10:02:50,349 pool-4-thread-19 ERROR o.a.f.i.DefaultFtpHandler:157 - Exception caught, closing session
javax.net.ssl.SSLHandshakeExce...Please explore how we can reduce the verbosity of apache mina (FTP). The logs are filling up with:
```
10:02:50,349 pool-4-thread-19 ERROR o.a.f.i.DefaultFtpHandler:157 - Exception caught, closing session
javax.net.ssl.SSLHandshakeException: SSL handshake failed.
at org.apache.mina.filter.ssl.SslFilter.messageReceived(SslFilter.java:519)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:542)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:947)
at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:109)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:542)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:535)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:703)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:659)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:648)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$600(AbstractPollingIoProcessor.java:68)
at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1120)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
at sun.security.ssl.EngineInputRecord.bytesInCompletePacket(EngineInputRecord.java:156)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:868)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at org.apache.mina.filter.ssl.SslHandler.unwrap(SslHandler.java:754)
at org.apache.mina.filter.ssl.SslHandler.unwrapHandshake(SslHandler.java:689)
at org.apache.mina.filter.ssl.SslHandler.handshake(SslHandler.java:575)
at org.apache.mina.filter.ssl.SslHandler.messageReceived(SslHandler.java:360)
at org.apache.mina.filter.ssl.SslFilter.messageReceived(SslFilter.java:500)
... 15 more
```
Can we just log the exception message?2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/415Better exceptions2019-02-19T15:09:36+01:00Matija ObrezaBetter exceptionsWe are using both `org.genesys2.spring.ResourceNotFoundException` and the `NotFoundElement?Exception`. Please consolidate the code so that one of these is used (the `NotFound` one) because it already uses nice logging.
```
14:20:51,979 ...We are using both `org.genesys2.spring.ResourceNotFoundException` and the `NotFoundElement?Exception`. Please consolidate the code so that one of these is used (the `NotFound` one) because it already uses nice logging.
```
14:20:51,979 qtp2027961269-14 ERROR o.g.s.a.ApiExceptionHandler:211 - Wow! Such! Exception!
org.genesys2.spring.ResourceNotFoundException
at org.genesys2.server.service.impl.AccessionServiceImpl.getAccessionDetails(AccessionServiceImpl.java:162)
...
...
```
## Throw `InvalidApiUsageException` in:
```
java.lang.RuntimeException: Refusing to export more than 200000 entries
at org.genesys2.server.mvc.ExplorerController.kml(ExplorerController.java:775)
```
Check code where it makes sense to replace `RuntimeException` with `InvalidApiUsageException`, for example:
```
java.lang.RuntimeException: Could not render image
at org.genesys2.server.mvc.ExplorerController.tile(ExplorerController.java:830)
at org.genesys2.server.mvc.ExplorerController$$FastClassBySpringCGLIB$$827bbdf0.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
```
```
Caused by: java.lang.RuntimeException: Could not parse date yyyy-M-d from --
at org.genesys2.server.service.filter.AppliedFiltersConverter.parseDate(AppliedFiltersConverter.java:362)
at org.genesys2.server.service.filter.AppliedFiltersConverter.lambda$convertDateFilter$5(AppliedFiltersConverter.java:333)
at java.lang.Iterable.forEach(Iterable.java:75)
```
```
java.lang.RuntimeException: Could not convert filters
at org.genesys2.server.service.impl.FilterHandler$AppliedFilters.convert(FilterHandler.java:517)
at org.genesys2.server.mvc.ExplorerController.viewFiltered(ExplorerController.java:240)
at org.genesys2.server.mvc.ExplorerController$$FastClassBySpringCGLIB$$827bbdf0.invoke(<generated>)
```
## There's an NPE
```
13:00:51,218 qtp2027961269-2490 ERROR o.g.s.m.UserControllerAdvice:103 - null on GET http://www.genesys-pgr.org/expl
java.lang.NullPointerException
at org.genesys2.server.service.filter.AccessionFilter.buildQuery(AccessionFilter.java:286)
at org.genesys2.server.service.filter.AccessionFilter.buildPredicate(AccessionFilter.java:116)
```
## And this
```
Caused by:
javax.servlet.ServletException: java.lang.IllegalStateException: Page needs a session and none is available
at org.apache.jsp.WEB_002dINF.jsp.errors.error_jsp._jspService(error_jsp.java:235)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:443)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
```2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/416Update of Accession Aliases2019-02-17T16:04:52+01:00Matija ObrezaUpdate of Accession AliasesThe current code in `AccessionUploader` doesn't handle some cases very well.
There must be only one entry of type `DONORNUMB` with `donorNumb` and `donorCode` sourced from the incoming accession *JSON*. The code should simply update the...The current code in `AccessionUploader` doesn't handle some cases very well.
There must be only one entry of type `DONORNUMB` with `donorNumb` and `donorCode` sourced from the incoming accession *JSON*. The code should simply update the existing `AccessionAlias` of type `DONORNUMB` with the provided values (`usedBy = donorCode`, `name = donorNumb`).
There can be multiple entries of type `BREDNUMB`, `ACCENAME` and others.2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/417AccessionData @Validation2019-02-17T16:04:53+01:00Matija ObrezaAccessionData @ValidationUpdate validation rules on `AccessionData` entity:
- Add **regex pattern** `[A-Z]{3}\\d{3,4}` to `donorCode`
- Same to `usedBy` in `AccessionAlias`
- Same to `collCode` in `AccessionCollect`
Make sure validations are executed before `A...Update validation rules on `AccessionData` entity:
- Add **regex pattern** `[A-Z]{3}\\d{3,4}` to `donorCode`
- Same to `usedBy` in `AccessionAlias`
- Same to `collCode` in `AccessionCollect`
Make sure validations are executed before `AccessionUploader` uses them.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/418Invalid handling of collCode, collNumb2019-02-17T16:04:54+01:00Matija ObrezaInvalid handling of collCode, collNumbGenesys partners sometimes submit `collCode` as an MCPD array string `COOD003;BEN089` instead of `["COOD003", "BEN089"]` array. Same for `collName`.
In API **v0** please add to `upgradeToV2` method some logic that will ensure these are ...Genesys partners sometimes submit `collCode` as an MCPD array string `COOD003;BEN089` instead of `["COOD003", "BEN089"]` array. Same for `collName`.
In API **v0** please add to `upgradeToV2` method some logic that will ensure these are converted to `String[]`.
Update `liquibase-changeLog.yml` with SQL that converts current incorrect data for `collCode` (e.g. `COOD003;BEN089`) to two records.
*Not sure how valid this SQL is, but it seems to work*
```yml
- sql:
drop table if exists t_collCode;
create table if not exists t_collCode as
select
@num_e := 1 + LENGTH(collCode) - LENGTH(REPLACE(collCode, ';', '')) AS num_e,
collectId, collCode,
SUBSTRING_INDEX(collCode,';',1) as coll1,
IF(@num_e > 1, SUBSTRING_INDEX(SUBSTRING_INDEX(collCode,';',2),';',-1), null) coll2,
IF(@num_e > 2, SUBSTRING_INDEX(SUBSTRING_INDEX(collCode,';',3),';',-1), null) coll3,
IF(@num_e > 3, SUBSTRING_INDEX(SUBSTRING_INDEX(collCode,';',3),';',-1), null) coll4
from accession_collect_code where collCode is not null and (LENGTH(collCode) - LENGTH(REPLACE(collCode, ';', ''))) > 0;
delete from accession_collect_code where collectId in (select distinct collectId from t_collCode);
insert into accession_collect_code (collectId,collCode)
(select distinct collectId, coll1 from
(select collectId, coll1 from t_collCode where coll1 is not null
union all select collectId, coll2 from t_collCode where coll2 is not null
union all select collectId, coll3 from t_collCode where coll3 is not null
union all select collectId, coll4 from t_collCode where coll4 is not null) Q);
drop table t_collCode;
```
Apparently we don't have any such problems in `accession_collect_name` table.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/419sitemap-INSTCODE.xml2019-02-11T11:53:41+01:00Matija Obrezasitemap-INSTCODE.xmlWe now generate the `sitemap-wiews.xml` that generates a sitemap to institute pages:
```java
for (FaoInstitute institute : instituteService.listActive(new PageRequest(0, Integer.MAX_VALUE))) {
writePage(response, sb, new SitemapPage("/...We now generate the `sitemap-wiews.xml` that generates a sitemap to institute pages:
```java
for (FaoInstitute institute : instituteService.listActive(new PageRequest(0, Integer.MAX_VALUE))) {
writePage(response, sb, new SitemapPage("/wiews/" + institute.getCode().toUpperCase()));
}
```
Instead it should reference another sitemap `sitemap-{INSTCODE}.xml` with the links to pages:
- `new SitemapPage("/wiews/" + institute.getCode().toUpperCase())`
- a `new SitemapPage("/a/...."` for every accession of that institute (use `AccessionProcessor`).2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/421Versioned Subsets2019-03-05T22:24:56+01:00Matija ObrezaVersioned SubsetsWe'd like to implement *versioned subsets*: subset may be updated by the data provider and (when published) both versions should be available through Genesys.
1. Obsolete subsets should not be listed by default
1. Obsolete subset must p...We'd like to implement *versioned subsets*: subset may be updated by the data provider and (when published) both versions should be available through Genesys.
1. Obsolete subsets should not be listed by default
1. Obsolete subset must point to a new version of the subset
## Simple approach
The very simple approach is to add `private Subset nextVersion` to the `Subset` entity and then we know that a subset has been replaced if `nextVersion != null`. And we can display a link to the new version.
**Problem:** This would only work if the new subset would be immediately published. But it has to go through review, and until the updated version is in `PUBLISHED` state we do not have any mechanism to say that the old version is "current" (the latest).
## Dataset approach
We have this implemented for `Dataset` in `DatasetVersions` (but we are not using it at the moment). Subsets are much simpler than datasets, so I suggest we try it here. We will need to introduce `SubsetVersions` (similar to `DatasetVersions`) and implement service methods that allow for the following:
1. The owner of a subset can create a new Subset based on an existing `PUBLISHED` Subset
1. If the existing subset is not published, reject the request.
1. A new `Subset` is created in `DRAFT` mode and **all data is copied** to the new version
1. The old and the new `Subset` both link to `SubsetVersions` entity
1. When the new `Subset` is **published** the `SubsetVersions#currentVersion` is changed to point to this version.
1. Queries for listing Subsets must only return latest versions:
1. `select s from Subset s where s.current = true and s.state = 'PUBLISHED'`.
1. Users can still access a subset that is **not current**, but it is published: `loadSubset` should only check that `state = 'PUBLISHED'`.
1. We cannot inner join `SubsetVersions` because we will not store that in the Elasticsearch.
1. The service methods must update `subset.current` when the new version is `PUBLISHED`.
1. Only one `Subset` of all versions of `SubsetVersions` can be current. This is best achieved with a unique key on `subset.versions + subset.current`, but we have to set `subset.current = null` when the subset is not the current version.
1. This means that `subset.current = true` means it is the currently published version and `subset.current = null` means it is not a current version.
### New Subsets
1. A new subset is created as it is created now, but a `SubsetVersions` is created for as well.
1. The new subset has `subset.current = null` and `SubsetVersions#currentVersion = null`.
1. When the subset is published, both these values are updated: `subset.current = true` and `SubsetVersions#currentVersion = ¤tSubset`.
## Un-publishing Subsets
If a `PUBLISHED` subset is unpublished (by an Administrator) we have the case when:
1. The subset is **not current** and it **must not** be unpublished. Reject.
1. The subset **is current**: we need to pick a subset that is published and that can replace the current version
1. If there is no other version of a subset (this is the first published version): set `subset.current = null` and `SubsetVersions#currentVersion = null`
1. If there are other published versions of the subset (in `SubsetVersions#allVersions`) then make the youngest (by `createdDate`) the currently published version.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/422Subsets: Partner as owner2019-02-26T09:23:31+01:00Matija ObrezaSubsets: Partner as ownerSubsets were designed and implemented before we had `Partner` in Genesys. This makes it very inconvenient for Administrators as users cannot see the subsets they've submitted (and we've rejected).
Please add `private Partner owner` to `...Subsets were designed and implemented before we had `Partner` in Genesys. This makes it very inconvenient for Administrators as users cannot see the subsets they've submitted (and we've rejected).
Please add `private Partner owner` to `Subset` in addition to the `institute` link. Permission checks should be done on `owner`, not on `institute`.
A user still should not be able to register a Subset on an `Institute` that they have no permission to `MANAGE` or `WRITE`. Best to have the UI render a dropdown with institutes belonging to a `Partner`.
Hopefully, this will allow people to see their subsets after they were modified by an Administrator. Check for permissions on `Partner` for listing the subsets.
**Note:** Requires changes to the frontend code. 2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/424AccessionUploader: delete operation2019-02-28T14:43:18+01:00Matija ObrezaAccessionUploader: delete operationThe `delete` operation in the AccessionUploader should be doing something very similar to `removeAccessions` in `GenesysServiceImpl`: it should copy the current `Accession` to `AccessionHistoric`.
I guess this function was forgotten whe...The `delete` operation in the AccessionUploader should be doing something very similar to `removeAccessions` in `GenesysServiceImpl`: it should copy the current `Accession` to `AccessionHistoric`.
I guess this function was forgotten when the new Uploader was implemented.
Please add a unit test.2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/425Versioned Datasets: update2019-03-25T18:34:15+01:00Matija ObrezaVersioned Datasets: updateUpgrade versioned Datasets to the approach implemented in #421Upgrade versioned Datasets to the approach implemented in #4212.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/426/geo and /iso31662019-03-04T18:29:46+01:00Matija Obreza/geo and /iso3166Make custom `X??` codes return 404 and exclude them from the country list.Make custom `X??` codes return 404 and exclude them from the country list.2.4Matija ObrezaMatija Obrezahttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/427Remove PublishValidationInterface2019-03-07T14:01:05+01:00Matija ObrezaRemove PublishValidationInterfaceRemove `PublishValidationInterface` as we're using javax validations.
CC @vpavlovRemove `PublishValidationInterface` as we're using javax validations.
CC @vpavlov2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/428MCPD coverage2019-03-17T12:03:29+01:00Matija ObrezaMCPD coveragePDCI is a mechanism to assess the coverage of accession passport data provided and it assigns different scores for fields for different types of accessions based on SAMPSTAT field.
We would like to see overall coverage of all passport d...PDCI is a mechanism to assess the coverage of accession passport data provided and it assigns different scores for fields for different types of accessions based on SAMPSTAT field.
We would like to see overall coverage of all passport data fields in Genesys database for a specified filter.
Add `missing` ES aggregation query for all fields of `Accession` that are serialized to JSON and stored to ES.
## Using JSON schema
1. Determine JSON schema for `Accession` and all related types
1. Take every field name (including nested properties) and find the `missing` value
The result will be a map of all JSON paths with their `missing` value. `totalCount` shows all records matching the filter.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/429Massive subsets/datasets2019-03-20T08:20:43+01:00Matija ObrezaMassive subsets/datasetsCreating subsets (or datasets) with 100,000s accession refs is a performance issue for the backend, especially because the UI request will time out before the server is done processing. The user also cannot know that the server is proces...Creating subsets (or datasets) with 100,000s accession refs is a performance issue for the backend, especially because the UI request will time out before the server is done processing. The user also cannot know that the server is processing the request and will re-upload the 100,000 refs, using more server resources.
Update the processing of AccessionRef uploads so that they require the current `version` of the dataset (or subset) to be correct before adding refs to it.
The UI ticket is genesys-pgr/genesys-ui#2562.4Andrey GarnitskiyAndrey Garnitskiyhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/430Improve caching2019-04-09T20:54:42+02:00Matija ObrezaImprove cachingFigure out best response for incoming HTTP headers that affect caching. At this moment resources cached by CloudFront seem to get refreshed:
![image](/uploads/acb1974d2aed815b0b66c5d587c75bd2/image.png) ![image](/uploads/aa88cfa2b1c5178...Figure out best response for incoming HTTP headers that affect caching. At this moment resources cached by CloudFront seem to get refreshed:
![image](/uploads/acb1974d2aed815b0b66c5d587c75bd2/image.png) ![image](/uploads/aa88cfa2b1c5178e3ea99b4e3082f425/image.png)
Update cache response headers so that resources stay cached longer in our AWS Cloudfront.
## TODO
Return `Not modified` when (see `#clientCacheValid()`).
- Client header `Etag` matches
- Header `If-Modified-Since` matches `lastModifiedDate`
- Other headers?
- Return `Not modified` HTTPS status as soon as possible in code
- Consider updating `maxage`
Start with code in `RepositoryDownloadController` **v1**, then check all server code that now returns cache headers and add better cache-handling when possible.2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/432Descriptor lists: Overview2019-03-28T10:09:35+01:00Matija ObrezaDescriptor lists: OverviewSimilar to Accession pages, we would like to add **Overview** page for `DescriptorLists` (including when filtered). This requires a new API endpoint.
Term summaries for:
- Data provider
- CropSimilar to Accession pages, we would like to add **Overview** page for `DescriptorLists` (including when filtered). This requires a new API endpoint.
Term summaries for:
- Data provider
- Crop2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/433Access token as Cookie2019-04-15T10:11:40+02:00Matija ObrezaAccess token as CookieThe `/proxy` handler in expressjs (https://gitlab.croptrust.org/genesys-pgr/genesys-ui/blob/master/server/middleware/httpProxy.ts#L18-25) checks request cookies for `access_token` and converts it to `Authorization: Bearer ...` HTTP heade...The `/proxy` handler in expressjs (https://gitlab.croptrust.org/genesys-pgr/genesys-ui/blob/master/server/middleware/httpProxy.ts#L18-25) checks request cookies for `access_token` and converts it to `Authorization: Bearer ...` HTTP header before forwarding the request to the API server.
## Servlet
We need the API server to respect the `access_token` cookie, not just the `Authorization` HTTP request header. Maybe Spring Security libraries allow for this. If not, we need a servlet that is processed **before** OAuth auth servlets in the API that converts the cookie to the `Authorization: Bearer ...` header.
When this is implemented, we can remove the `/proxy` handler from `genesys-new-ui` project and update all HTTP links that start with `/proxy/**` to point to API URL directly.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/434Filter by genus+species2019-04-10T16:13:47+02:00Matija ObrezaFilter by genus+speciesAllow for filtering on full species name, not just the specific epithet portion of the scientific name.
Add `genusSpecies` to `TaxonomyFilter` which will look up `Taxonomy2` records by `taxSpecies` identifier. The filter code must first...Allow for filtering on full species name, not just the specific epithet portion of the scientific name.
Add `genusSpecies` to `TaxonomyFilter` which will look up `Taxonomy2` records by `taxSpecies` identifier. The filter code must first lookup the ID and apply it directly.2.4Matija ObrezaMatija Obrezahttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/435Accession filters autocomplete2019-04-12T11:19:24+02:00Matija ObrezaAccession filters autocompletehttp://localhost:3000/proxy/api/v1/acn/autocomplete/countryOfOrigin.code3?f=&term=slove does not find `SVN` for Slovenia.http://localhost:3000/proxy/api/v1/acn/autocomplete/countryOfOrigin.code3?f=&term=slove does not find `SVN` for Slovenia.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/436Accession page URL2019-04-15T12:47:33+02:00Matija ObrezaAccession page URLThe new website uses `/a/{uuid}` URL to access individual accession data. The JSP version still uses `/acn/id/{id}`. Both versions support the `/10.xxx/xxxx` URL using accession DOI.
Replace `/acn/id/{id}` with `/a/{uuid}` in JSPs and m...The new website uses `/a/{uuid}` URL to access individual accession data. The JSP version still uses `/acn/id/{id}`. Both versions support the `/10.xxx/xxxx` URL using accession DOI.
Replace `/acn/id/{id}` with `/a/{uuid}` in JSPs and make a permanent redirect from `/acn/id/{id}` to `/a/{uuid}`.2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/437Sitemap update2019-04-16T20:10:28+02:00Matija ObrezaSitemap updateThe sitemaps need updating; the root `sitemap.xml` now includes the following sub-sitemaps:
```xml
<loc>http://localhost:3000/sitemap-content.xml</loc>
<loc>http://localhost:3000/sitemap-geo.xml</loc>
<loc>http://localhost:3000/sitemap-...The sitemaps need updating; the root `sitemap.xml` now includes the following sub-sitemaps:
```xml
<loc>http://localhost:3000/sitemap-content.xml</loc>
<loc>http://localhost:3000/sitemap-geo.xml</loc>
<loc>http://localhost:3000/sitemap-wiews.xml</loc>
<loc>http://localhost:3000/sitemap-crop.xml</loc>
```
## `sitemap-content.xml`
It now has:
```xml
<loc>http://localhost:3000/welcome</loc>
<loc>http://localhost:3000/content/about</loc>
<loc>http://localhost:3000/explore/overview</loc>
<loc>http://localhost:3000/wiews/active</loc>
<loc>http://localhost:3000/content/terms</loc>
<loc>http://localhost:3000/explore</loc>
<loc>http://localhost:3000/org/</loc>
```
Instead it should list:
- `/`
- `/content/about/about`
- `/content/legal/terms`
- `/content/legal/disclaimer`
- `/documentation/apis`
- `/documentation/brapi`
- List of all `Activity posts` with their links `/content/news/72/....`
## `sitemap-geo.xml`
Rename it to `sitemap-iso3166.xml`. It should include custom ISO3166 codes (the XXX codes).
## Add `sitemap-partner.xml`
List links to all Genesys data providers `/partner/...`.
## `sitemap-crop.xml`
Should link to the crop pages, not to `../data`.
## New sitemaps
Add `sitemap-XXX.xml` for PUBLISHED **subsets**, **datasets** and **descriptor lists**.
- `sitemap-subset.xml` lists links to all published Subsets
- ...2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/439Use ES for text queries2019-05-01T21:52:50+02:00Matija ObrezaUse ES for text queriesWhen user provides `_text` filter (keyword search) the backend should query ES for results (not the database).
We have `_text` filter in `DescriptorListFilter` for example. Add `_text` filter to `AccessionFilter`.
This requires adding ...When user provides `_text` filter (keyword search) the backend should query ES for results (not the database).
We have `_text` filter in `DescriptorListFilter` for example. Add `_text` filter to `AccessionFilter`.
This requires adding support for converting `_text` field to a full-text ES query (https://www.elastic.co/guide/en/elasticsearch/reference/2.3/full-text-queries.html) in `ElasticQueryBuilder`.
Explore if this is possible.
##
```java
public Page<Accession> list(AccessionFilter filter, Pageable page) {
if (StringUtils.isNotBlank(filter._text)) {
// FIXME Use ES to list matches
elasticsearchService.findAll(Accession.class, filter, page);
} else {
List<Accession> content = accessionRepository.findAll(filter, page);
}
long total = countAccessions(filter);
return new PageImpl<>(content, page, total);
}
```2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/440Inconsistent API response2019-05-06T11:34:33+02:00Matija ObrezaInconsistent API responseReported by @osavran, the descriptors sort property from response has this structure:
![Screenshot_from_2019-05-03_09-16-59](/uploads/0bfa68e143c0f780eb545e3a54065963/Screenshot_from_2019-05-03_09-16-59.png)
and for other modules:
![S...Reported by @osavran, the descriptors sort property from response has this structure:
![Screenshot_from_2019-05-03_09-16-59](/uploads/0bfa68e143c0f780eb545e3a54065963/Screenshot_from_2019-05-03_09-16-59.png)
and for other modules:
![Screenshot_from_2019-05-03_09-12-37](/uploads/339d1a3b521f6a138330af494b8e364a/Screenshot_from_2019-05-03_09-12-37.png)
`PaginationComponent` throw error "`pageObj.sort[0]` is undefined", descriptors action `updateRoute` also won't work. I think the same problem is in other components.
## Notes
This may have to do with difference between ES and JPA `Page<?>` responses.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/443ES not containing all data2019-05-19T18:10:09+02:00Matija ObrezaES not containing all dataDatasets ES index does not list different data providers. See https://beta.genesys-pgr.org/datasets/overview.
Another issue is with updating only one part of the ES document: When the image count is updated to the database, we do not us...Datasets ES index does not list different data providers. See https://beta.genesys-pgr.org/datasets/overview.
Another issue is with updating only one part of the ES document: When the image count is updated to the database, we do not use the entity update so that the Auditor doesn't update `lastModifiedDate`. But this results in ES not being updated.
We uploaded images for 2 accessions at https://beta.genesys-pgr.org/a/overview/v16f1def008dbf46969dc325f668c676d1 and the Overview doesn't show data for these. Can we partially update an ES document with only `{ accessionCount: 2 }`?2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/444ACCENAME in AccessionData2019-05-21T09:38:33+02:00Matija ObrezaACCENAME in AccessionDataDifferent names of an accession are stored as `AccessionAlias` and one accession has a list of them.
See if we can add `getAccessionName` that returns the first alias of type `ACCENAME`. This, in theory, should force lazy loading the a...Different names of an accession are stored as `AccessionAlias` and one accession has a list of them.
See if we can add `getAccessionName` that returns the first alias of type `ACCENAME`. This, in theory, should force lazy loading the aliases list. But we don't need to change the database.
I think in the past we misused the `getAccessionName` to return `accessionNumber`. If we have any EL expressions in JSP that use `accessionName` they should be modified to `accessionNumber`.2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/445Request API: remove request2019-05-15T23:56:17+02:00Matija ObrezaRequest API: remove requestRequest database contains records that are duplicates or test requests. Please add `remove` endpoint to Request API, only for ADMIN accounts.Request database contains records that are duplicates or test requests. Please add `remove` endpoint to Request API, only for ADMIN accounts.2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/446Better thumbnail quality2019-05-21T20:06:19+02:00Matija ObrezaBetter thumbnail qualityCurrent code to generate thumbnails does not produce good quality thumbs. See for example some of the crop images in the crops list page.
The issue is most visible with very high-quality source images, compare the generated thumbnail to...Current code to generate thumbnails does not produce good quality thumbs. See for example some of the crop images in the crops list page.
The issue is most visible with very high-quality source images, compare the generated thumbnail to the original image:
- https://beta.genesys-pgr.org/10.18730/H8F64
- https://beta.genesys-pgr.org/10.18730/H8PVV
- https://beta.genesys-pgr.org/10.18730/HTM8R2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/447ES reindexing using BasicFilter2019-05-22T18:46:16+02:00Matija ObrezaES reindexing using BasicFilterAt the moment Genesys allows for reindexing of selected records using JSON filters in admin pages of JSP.
Please add API v1 endpoint(s) to reindex selected records (as in JSP) and add it to UI.At the moment Genesys allows for reindexing of selected records using JSON filters in admin pages of JSP.
Please add API v1 endpoint(s) to reindex selected records (as in JSP) and add it to UI.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/448DownloadService with ES2019-05-21T11:06:17+02:00Matija ObrezaDownloadService with ESWhen using full text filtering with ES, the downloads are disabled because DownloadService (and AccessionProcessor) support JPA queries only. Refactor the code so that PccessionProcessor can use ES or JPA filters to generate downloads.When using full text filtering with ES, the downloads are disabled because DownloadService (and AccessionProcessor) support JPA queries only. Refactor the code so that PccessionProcessor can use ES or JPA filters to generate downloads.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/451Delete Metadata2019-06-05T04:47:54+02:00Matija ObrezaDelete MetadataAllow for removing old `org.genesys2.server.model.genesys.Metadata` (e.g. https://www.genesys-pgr.org/data/view/3673) and all related `ExperimentAccessionTrait`, `ExperimentTrait` for administrator in the JSP page.Allow for removing old `org.genesys2.server.model.genesys.Metadata` (e.g. https://www.genesys-pgr.org/data/view/3673) and all related `ExperimentAccessionTrait`, `ExperimentTrait` for administrator in the JSP page.2.4Matija ObrezaMatija Obrezahttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/452Descriptor image and language2019-06-18T08:13:31+02:00Matija ObrezaDescriptor image and languageAdd `private RepositoryImage image` and `@MaxLength(2) private String lang` to `Descriptor`. The image should be loaded in `lazyLoad(Descriptor)`.
Extend Descriptor API v1 with methods: `updateImage(Descriptor d, ...)` and `removeImage(...Add `private RepositoryImage image` and `@MaxLength(2) private String lang` to `Descriptor`. The image should be loaded in `lazyLoad(Descriptor)`.
Extend Descriptor API v1 with methods: `updateImage(Descriptor d, ...)` and `removeImage(Descriptor r)`. Ensure API supports `lang` property.
The descriptor image should be saved at repository path `/descriptor/{uuid.substring(0,3)}/{uuid}.{ext}`.
Ensure the `descriptor.image` is included in JSON response for Descriptor Lists.2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/453Request failed when user try apply "Not specified" filter on the "Accession b...2019-07-14T21:12:35+02:00Kiril MorhalenkoRequest failed when user try apply "Not specified" filter on the "Accession browser" pageSteps to reproduce:
1. Open "https://sandbox.genesys-pgr.org/a/overview"
2. Apply "Not specified" filter from "Genus" block
Expected result:
Filter is applied and results are shown
Actual result:
> Error happened while processing requ...Steps to reproduce:
1. Open "https://sandbox.genesys-pgr.org/a/overview"
2. Apply "Not specified" filter from "Genus" block
Expected result:
Filter is applied and results are shown
Actual result:
> Error happened while processing request:
>
> "Request failed with status code 500 Error accessing field taxonomy.genus for isNull() in class org.genesys2.server.model.genesys.QAccession"
This bug reproduce with "Genys", "Type of Germplasm storage" and "Provenance of material" blocks
![Request_failed](/uploads/dfc0204d491abdbb29ca29a45790145c/Request_failed.gif)2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/457FilterCode v22019-06-22T05:49:57+02:00Matija ObrezaFilterCode v2Filter encoding **version 1** uses a randomly generated UUID with `-` removed:
```java
private String generateShortNameV1() {
for (int i = 0; i < 10; i++) {
final String code = "v1" + UUID.randomUUID().toString().replace("-", "");
...Filter encoding **version 1** uses a randomly generated UUID with `-` removed:
```java
private String generateShortNameV1() {
for (int i = 0; i < 10; i++) {
final String code = "v1" + UUID.randomUUID().toString().replace("-", "");
// return shortName if unique
if (shortFilterRepository.findByCode(code) == null) {
return code;
}
}
throw new RuntimeException("Failed to generate a unique filters short name in several attempts");
}
```
This generates filter codes like `v1a37ad370d9ca4f62b3d9840094aafae9` and they are fairly long.
## Shorter filter codes
We can make use of https://hashids.org/java/ to generate shorter codes with a custom salt!
Initial idea is to use the current timestamp (long value, 4b), resulting in drastically smaller unique short filter codes.
```java
private String generateShortNameV2() {
Hashids hashids = new Hashids("this is my salt");
for (int i = 0; i < 10; i++) {
String hash = hashids.encode(System.currentTimeMillis());
final String code = "v2" + hash;
// return shortName if unique
if (shortFilterRepository.findByCode(code) == null) {
return code;
}
}
throw new RuntimeException("Failed to generate a unique filters short name in several attempts");
}
```
We could extend this to our use of UUIDs in URLs, and see if that makes a difference in URL `code` length.2.4Matija ObrezaMatija Obrezahttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/458Requests for material without PID2019-08-02T10:51:04+02:00Matija ObrezaRequests for material without PIDGenesys now requires that all requests for material obtain the Easy-SMTA PID before relaying the request to the holding genebanks.
Requests for material can be "internal" (within the institute), meaning that no SMTA is required.
Add su...Genesys now requires that all requests for material obtain the Easy-SMTA PID before relaying the request to the holding genebanks.
Requests for material can be "internal" (within the institute), meaning that no SMTA is required.
Add support for **Internal requests** through Genesys; add an option "Internal request (no S/MTA required)" to Genesys and skip the Easy-SMTA checks that are currently required for the request to be relayed to the genebank.
2.4Maxym BorodenkoMaxym Borodenkohttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/461Geo Countries list2019-07-30T17:11:58+02:00Matija ObrezaGeo Countries listhttps://api.sandbox.genesys-pgr.org/api/v1/geo/countries returns a massive JSON. If we don't use `nameL` on the frontend, please don't include it in response to this call.https://api.sandbox.genesys-pgr.org/api/v1/geo/countries returns a massive JSON. If we don't use `nameL` on the frontend, please don't include it in response to this call.2.4Viacheslav PavlovViacheslav Pavlovhttps://gitlab.croptrust.org/genesys-pgr/genesys-server/-/issues/465Document migration from API v0 to v12019-09-16T20:38:44+02:00Matija ObrezaDocument migration from API v0 to v1......2.4Matija ObrezaMatija Obreza