radar-base / managementportal Goto Github PK
View Code? Open in Web Editor NEWManagement Portal to manage research studies
License: Apache License 2.0
Management Portal to manage research studies
License: Apache License 2.0
Our service needs to provide endpoints for single sign-on login and OAuth2 token generation and validation.
Create basic entities using defined schema. Currently, these entities are planned to be implemented.
Currently, the patient resources transforms whole nested data in and out.
To improve the amount of data transfered, transfer related ids of ManyToMany relationship and fetch data on demand. Current situation requires to fetch nested data eagerly.
Currently a user can be created based on a role. A role is a unique combination of Project and Authority.
If a Role has to be removed, a prior validations should be made to check whether any User entities are created for specific role. If not allow detete-role for super-super.
We need to revoke the access-token and refresh token related to a subject when a subject is removed or discontinued
There are several places where we want to input timestamp data. A date-selector component should be integrated or integrated date-selector should be investigated and work as expected.
Currently we are loading oauth-client credentials
from csv. The test credentials used for dev/testing are publicly available. We need to find a way to securely handle this for production environment. Maybe mounting csv file as volume would help in docker compose? and add some environment variables to load values for MP front-end.
Any suggestions are welcome. @dennyverbeeck
Document the work-flow of a project initialization work-flow with a PROJECT-OWNER.
A PROJECT_OWNER is similar to SYS_ADMIN, but can only handle entities related to his project only.
Only the SYS_ADMIN can have access to all the operations in the portal.
Currently, only ROLE_ADMIN and ROLE_USER authorities are supported when creating a user. The system should allow to choose from available ROLES (USER_ROLES in future).
We want to allow only unique combination of AuthorityName and ProjectId in Role. This could be added to persistent layer. Also investigate on providing comprehensive error message for user on failed scenarios.
Alongside with REDCap
and RADAR
ids, we can create a simple human readable identifier using the concatenation of
metadata
.The generated value will be unique as long as a site will use a single REDCap instance.
It would be useful to have some way of entering structured exercises and questionnaires to the management portal. Perhaps check with @kerzmaximilian, @fnobilia and @hesamsagha what properties would be useful there.
To synchronize with RADAR components, certain entity schema should be updated according to RADAR-Schemas.
Create the basic entities and relationships to manage a pilot study
To integrate with usual packaging of the platform, MP should be dockorized with available, configuration options and integrated with docker-compose with relevant security measures taken into account.
Create a simple patient registration form with the following
For the API design of users and subjects, it would help to use the login
property as a path parameter everywhere instead of id
, since the login
is encoded in the JWT and id
is not. I understand it is already set to be unique, possibly it would also need an index?
Currently, once a source is assigned to a subject, it cannot be unassigned. It is possible to assign to other sources. But it is not possible to have no sources assigned. This should be possible, as an authorized user
Newly added entities such as subject, sources, device types should be supported to have pageable queries like users
To validate the data transmission at RADAR-Gateway, we need to provide enough additional information with the JWT token.
E.g. Set of assigned device ids, patient-login( user-id)
According to conventions in other components of the project we will treat a device as a source and a Patient as a Subject. Update entity, schema, resources, services and user-interfaces accordingly
As mentioned in issue#20, we want to allow dynamic device registration with dynamic ids for mobile devices.
The model should be enhanced to have a hasDynamicId for a deviceType and should provide a rest-resource to register a device.
The registered device should be listed under device list as the other devices.
Decided basic user authorities and Roles. Roles can be created with a combination of authority and a project. This gives the flexibility to have different set of authorities for different projects
Currently, the application doesn't automatically redirect to sign-in page when session expires, in stead it allows the ui interactions and responds with Unauthorized exception
. This behavior should be improved to detect the session expiry and load sign-in page.
One of the standard fields in a JWT is sub
(subject), which is the global ID of the user in the system, but Spring apparently does not generate it. It does generate user_name
, but that is not a standard. Proposal: the sub
field should match the userId
field that the Kafka streams use. In the case that people are using the ManagementPortal for user and ID management, that would be the user ID, if an external user management system is used and that system exposes the userId
that researchers want to use, could sub
be set to be the externalId
?
Deleting assigned source using delete
button in sources page list returns internal server error. It would be better to report something different from internal server error
Steps:
2017-09-01 13:38:38.034 DEBUG 1857 --- [ XNIO-2 task-6] o.r.m.aop.logging.LoggingAspect : Enter: org.springframework.boot.actuate.audit.AuditEventRepository.add() with argument[s] = [AuditEvent [timestamp=Fri Sep 01 13:38:38 UTC 2017, principal=admin, type=AUTHENTICATION_SUCCESS, data={details=remoteAddress=127.0.0.1, tokenType=BearertokenValue=}]]
Hibernate: insert into jhi_persistent_audit_event (event_id, event_date, event_type, principal) values (null, ?, ?, ?)
2017-09-01 13:38:38.035 DEBUG 1857 --- [ XNIO-2 task-6] o.r.m.aop.logging.LoggingAspect : Exit: org.springframework.boot.actuate.audit.AuditEventRepository.add() with result = null
Hibernate: insert into jhi_persistent_audit_evt_data (event_id, name, value) values (?, ?, ?)
2017-09-01 13:38:38.037 DEBUG 1857 --- [ XNIO-2 task-6] o.r.m.aop.logging.LoggingAspect : Enter: org.radarcns.management.web.rest.SourceResource.deleteSource() with argument[s] = [1]
2017-09-01 13:38:38.037 DEBUG 1857 --- [ XNIO-2 task-6] o.r.management.web.rest.SourceResource : REST request to delete Source : 1
2017-09-01 13:38:38.037 DEBUG 1857 --- [ XNIO-2 task-6] o.r.m.aop.logging.LoggingAspect : Enter: org.radarcns.management.service.SourceService.delete() with argument[s] = [1]
2017-09-01 13:38:38.037 DEBUG 1857 --- [ XNIO-2 task-6] o.r.management.service.SourceService : Request to delete Source : 1
Hibernate: select attributes0_.id as id1_13_0_, attributes0_.attribute_value as attribut2_13_0_, attributes0_.attribute_key as attribut3_0_ from source_metadata attributes0_ where attributes0_.id=?
2017-09-01 13:38:38.040 DEBUG 1857 --- [ XNIO-2 task-6] o.r.m.aop.logging.LoggingAspect : Exit: org.radarcns.management.service.SourceService.delete() with result = null
Hibernate: delete from radar_source where id=?
2017-09-01 13:38:38.047 WARN 1857 --- [ XNIO-2 task-6] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23503, SQLState: 23503
2017-09-01 13:38:38.047 ERROR 1857 --- [ XNIO-2 task-6] o.h.engine.jdbc.spi.SqlExceptionHelper : Referential integrity constraint violation: "FK_SUBJECT_SOURCES_SOURCES_ID: PUBLIC.SUBJECT_SOURCES FOREIGN KEY(SOURCES_ID) REFERENCES PUBLIC.RADAR_SOURCE(ID) (1)"; SQL statement:
delete from radar_source where id=? [23503-193]
2017-09-01 13:38:38.047 ERROR 1857 --- [ XNIO-2 task-6] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
2017-09-01 13:38:38.049 ERROR 1857 --- [ XNIO-2 task-6] o.r.m.aop.logging.LoggingAspect : Exception in org.radarcns.management.web.rest.SourceResource.deleteSource() with cause = 'org.hibernate.exception.ConstraintViolationException: could not execute statement' and exception = 'could not execute statement; SQL [n/a]; constraint ["FK_SUBJECT_SOURCES_SOURCES_ID: PUBLIC.SUBJECT_SOURCES FOREIGN KEY(SOURCES_ID) REFERENCES PUBLIC.RADAR_SOURCE(ID) (1)"; SQL statement:
delete from radar_source where id=? [23503-193]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement'
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["FK_SUBJECT_SOURCES_SOURCES_ID: PUBLIC.SUBJECT_SOURCES FOREIGN KEY(SOURCES_ID) REFERENCES PUBLIC.RADAR_SOURCE(ID) (1)"; SQL statement:
delete from radar_source where id=? [23503-193]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:278)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504)
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.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
at org.radarcns.management.service.SourceService$$EnhancerBySpringCGLIB$$3385fea4.delete()
at org.radarcns.management.web.rest.SourceResource.deleteSource(SourceResource.java:156)
at org.radarcns.management.web.rest.SourceResource$$FastClassBySpringCGLIB$$d7b58540.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at org.radarcns.management.aop.logging.LoggingAspect.logAround(LoggingAspect.java:73)
at sun.reflect.GeneratedMethodAccessor336.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
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.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:48)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:34)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
at org.radarcns.management.web.rest.SourceResource$$EnhancerBySpringCGLIB$$5aeac5a3.deleteSource()
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:116)
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:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:894)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:111)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
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:114)
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:170)
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.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.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:176)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
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:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.SessionRestoringHandler.handleRequest(SessionRestoringHandler.java:119)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:211)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:809)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3315)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3552)
at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:99)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:586)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:460)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1428)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:484)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3190)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2404)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
... 148 common frames omitted
Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FK_SUBJECT_SOURCES_SOURCES_ID: PUBLIC.SUBJECT_SOURCES FOREIGN KEY(SOURCES_ID) REFERENCES PUBLIC.RADAR_SOURCE(ID) (1)"; SQL statement:
delete from radar_source where id=? [23503-193]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:426)
at org.h2.constraint.ConstraintReferential.checkRowRefTable(ConstraintReferential.java:443)
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:318)
at org.h2.table.Table.fireConstraints(Table.java:967)
at org.h2.table.Table.fireAfterRow(Table.java:985)
at org.h2.command.dml.Delete.update(Delete.java:101)
at org.h2.command.CommandContainer.update(CommandContainer.java:98)
at org.h2.command.Command.executeUpdate(Command.java:258)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:160)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:146)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:205)
... 166 common frames omitted
2017-09-01 13:38:38.055 DEBUG 1857 --- [ XNIO-2 task-6] o.r.m.aop.logging.LoggingAspect : Enter: org.radarcns.management.web.rest.errors.ExceptionTranslator.processRuntimeException() with argument[s] = [org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["FK_SUBJECT_SOURCES_SOURCES_ID: PUBLIC.SUBJECT_SOURCES FOREIGN KEY(SOURCES_ID) REFERENCES PUBLIC.RADAR_SOURCE(ID) (1)"; SQL statement:
delete from radar_source where id=? [23503-193]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement]
2017-09-01 13:38:38.055 DEBUG 1857 --- [ XNIO-2 task-6] o.r.m.aop.logging.LoggingAspect : Exit: org.radarcns.management.web.rest.errors.ExceptionTranslator.processRuntimeException() with result = <500 Internal Server Error,org.radarcns.management.web.rest.errors.ErrorVM@799f9d56,{}>
2017-09-01 13:38:38.056 WARN 1857 --- [ XNIO-2 task-6] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["FK_SUBJECT_SOURCES_SOURCES_ID: PUBLIC.SUBJECT_SOURCES FOREIGN KEY(SOURCES_ID) REFERENCES PUBLIC.RADAR_SOURCE(ID) (1)"; SQL statement:
delete from radar_source where id=? [23503-193]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
We want to have default deviceTypes created from a deviceCatelog.yml that is generic for all the projects. Integration of deviceCatelog.yml should be provided to create static instance of deviceTypes from catelog and assign deviceTypes created from device catalog for a project that can be configurable
Creating a subject in the project view also triggers the creation of a user. However the email address supplied does not propagate to the user. This results in updates on the user causing errors, since the email is required. E.g. trying to activate a user that has no associated email address results in an internal server error.
The email address should propagate from the created subject to the created user.
Add single sign on login form, where e.g. dashboard can redirect it's users to to log in to the system.
We need a mechanism to easily package and distribute MP.
We should audit/log all operations that a Management Portal user does. In this way there is a clear understanding of who did what and when
.
We want to allow assigning multiple devices for a patient. One device can be assigned to only one patient actively.
If a device-patient assignment is canceled, it should be possible reassign this device to another patient.
Default application uses Authorities.
Create Role entity, an extended entity of Authorities to link it to a project if necessary
Modify existing relationship between User and Authorities to User and rRole. This should correctly reflect in authentication and authorization of endpoints and features for ROLE_ADMIN, ROLE_USER as of now.
We need to have a mechanism to have user-friendly, still anonymous and unique id to be used as the user-name/login of a patient. This is should be generated by the back-end and per-persisted. Once a patient is being created it should be saved as the user.login.
This would allow us to have server-side validations of the unique id before the patient is being created
Some suggested enhancements for subject enrollment:
We want to allow device registration for a project by PROJECT_ADMIN.
These devices can later be assigned to Patients assigned to specific project.
Currently, we support only one oauth2 client in the system. According to current situation, clients who wants to request tokens should share the client-id and client-secret internally. This is acceptable for trusted clients. This should be extended to allow multiple Oauth2 client registration like other identity provides, with custom client-id, client-secret, and scope.
This should be discussed in detail.
We need to discuss and decide what data are expected from Dashboard component from MP.
Accordingly, REST end-points should be implemented and/or adapted .
This integration should be validated with Dashboard.
As a User, i should be able to play different roles in one or more project. A SYS_ADMIN
user is a super user, who has privileges to access all projects and will be the only role the does not depend on a project.
Request for comments from @fnobilia, @nivemaham, @dennyverbeeck.
In the pRMT app, the user ID and assigned source IDs can be figured out from the JWT. The app needs a few calls to consolidate its device assignment:
The first two pieces of information could be provided in a single request:
HTTP GET /api/user/devices
Response:
HTTP 200
{
"devices": [
{
"id": "some-uuid",
"expectedName": "A00017",
"expectedSourceId": "null",
"deviceType": {
"id": "my-uuid",
"name": "EmpaticaE4",
"topics": {
"android_empatica_e4_acceleration": {
"key_schema": "org.radarcns.key.MeasurementKey",
"value_schema": "org.radarcns.empatica.EmpaticaE4Acceleration",
"provider": "org.radarcns.empatica.EmpaticaE4Provider",
"enabled": true
}
}
}
},
{
"id": "some-uuid2",
"sourceId": "abcd-ewaefafa-agagagbawe-asdfas",
"deviceType": {
"id": "my-uuid2",
"name": "AndroidPhone",
"topics": {
"android_phone_acceleration": {
"key_schema": "org.radarcns.key.MeasurementKey",
"value_schema": "org.radarcns.phone.PhoneAcceleration",
"frequency": 16,
"provider": "org.radarcns.phone.PhoneSensorProvider",
"enabled": true
},
"android_phone_light": {
"key_schema": "org.radarcns.key.MeasurementKey",
"value_schema": "org.radarcns.phone.PhoneLight",
"frequency": 16,
"provider": "org.radarcns.phone.PhoneSensorProvider",
"enabled": false
},
"android_phone_call": {
"key_schema": "org.radarcns.key.MeasurementKey",
"value_schema": "org.radarcns.phone.PhoneCall",
"send_interval": 43200,
"provider": "org.radarcns.empatica.PhoneCallProvider",
"enabled": true
}
}
}
}
]
}
If a dynamic
device type was registered and assigned to a project, when this request hits, probably an empty device with that device type should be created. If device.expectedName
and device.expectedSourceId
are null
, then any device ID might be registered. The reasoning is, that a clinician may not know the technical source ID, but only the name of a device (e.g. "Empatica E4 - A00017". In another case, the source ID is autogenerated by the plugin (e.g. phone sensors) so the clinician cannot know the source ID in advance.
New devices could be registered as follows:
HTTP POST /api/user/devices
{
"devices": [
{
"id": "some-uuid",
"name": "Empatica E4 - A00017",
"sourceId": "AB:01:CD:23:EF:45",
"firmware": "E4-2.1.0",
"model": "E4.A",
"os": null
}
]
}
Response:
HTTP 204
or for an illegal request,
HTTP 400
{
"message": "Name or ID does not match acceptedIds."
}
The request uses the same UUIDs as provided in the previous response, and it registers a fixed sourceId
, plus possibly some optional metadata. The backend should check that either the name or the MAC-address should match what was in acceptableIds
.
After registration of all source IDs, the app should request a new JWT, which will include those source IDs.
We need to investigate the best way to integrate Rest-Api to use security mechanisms of MP to secure REST endpoints in rest-api application.
One cohesive option would be convert Rest-api as a spring project and use it as a ResourceServer
and use MP's AuthorizationServer
to ensure the authorization. (Preferable)
Otherwise we could provide a small distribution with annotations and integrate it with Rest-api.
We need to update, write new test cases for unit, integration and e2e in management portal for already implemented and defined functionalities.
Travis and Codacy integration should be done as of the other packages of the RADAR-CNS
We want to allow only one PROJECT_ADMIN for a project.
A project view that contains the entities of a project is preferred than the current UI set-up.
A dashboard like interface to view all the related entities of a project is currently being discussed. Any suggestions are welcomed in this design
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.