Coder Social home page Coder Social logo

restapi's Introduction

restapi's People

Contributors

andreysubbotin avatar artemglinov avatar dtaimanov avatar gglcrash avatar gorbunkov avatar klaus7 avatar knstvk avatar mitring avatar nikitashchienko avatar plakhov avatar soraksh avatar vadimbasko avatar vyacheslav-pushkin avatar web-devel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

restapi's Issues

Custom REST controllers improvements

@haulmont-git commented on Wed Dec 13 2017

Exposing services in REST have many limitations such as:

  • inability to work with files,
  • inability to work with headers (send redirect, send custom error status, etc.),
  • unobvious serialization behavior and customization,
  • ... more to come.

According to feedback, developers usually end up with creating custom Spring REST Controllers:

https://www.cuba-platform.com/discuss/t/there-is-a-way-to-generate-html-from-a-rest-api-call/3185/2
https://www.cuba-platform.com/discuss/t/how-to-restrict-rest-api-v2-to-allow-post-only/3166

So instead of reinventing spring-mvc within our REST services maybe we need to enhance custom controllers usage, here are some ideas on it:

  • Easier way to create controllers in REST context.
    ** Current configuration is quite [https://doc.cuba-platform.com/manual-6.4/rest_api_v2_custom_controllers.html verbose].
    ** Support creation from Studio.
  • Provide the same (unified) serialization across generic REST and Custom controllers.
  • Consider to remove REST out of the WEB module (portal?)

Original issue: https://youtrack.haulmont.com/issue/PL-10144

Introduce a synchronous mode for storing REST API tokens in cluster

Description

When a new REST API token is stored, it is distributed among all nodes of the cluster. Right now, it is done asynchronously. This may cause the problem: in the cluster under a high load the token may be obtained, passed to another node, but the token was not replicated to the second node yet. Probably we should introduce a synchronous way of doing this (like is done for user sessions cuba.syncNewUserSessionReplication).

In addition to using clusterManagerAPI.send(new TokenStoreAddAccessTokenMsg(.... we may optionally use the clusterManagerAPI.sendSync(new TokenStoreAddAccessTokenMsg( in the ServerTokenStoreImpl.

There may be an application property cuba.syncTokenReplication. The default value is false. In the ServerTokenStoreImpl all invocations of clusterManagerAPI.send must be replaced with sendAsync if the app property is set to true. See UserSessions.add(UserSession session) method as an example.

Updates

The config cuba.rest.syncTokenReplication is added, the default value is false.
If true, tokens will be sent to the cluster in a synchronous way.

Support jMockit 1.46

Environment

  • Platform version: 7.2
  • Addon version: 7.2

Description of the bug or enhancement

In the platform updated jMockit.
It is necessary to add an argument to run the tests correctly.

test {
        jvmArgs "-javaagent:${classpath.find { it.name.contains("jmockit") }.absolutePath}"
}

Related: cuba-platform/cuba#2151

RefreshToken and AccessToken entity classes are not enhanced

Environment

  • Platform version: 7.1
  • Addon version: 0.1-SNAPSHOT
  • Client type: Web

Description of the bug or enhancement

  • Minimal reproducible example

Run application on 7.1-SNAPSHOT with REST-API.

  • Actual behavior
2019-04-19 11:27:38.381 ERROR [main] com.haulmont.cuba.core.sys.persistence.EclipseLinkSessionEventListener - 
=================================================================
Problems with entity enhancement detected:
Entity class RefreshToken is missing some of enhancing interfaces: CubaEnhanced; PersistenceObject; PersistenceWeaved; PersistenceWeavedFetchGroups; PersistenceWeavedChangeTracking;
Entity class AccessToken is missing some of enhancing interfaces: CubaEnhanced; PersistenceObject; PersistenceWeaved; PersistenceWeavedFetchGroups; PersistenceWeavedChangeTracking;

Also, there is no entitiesEnhancing in build.gradle of the addon: https://github.com/cuba-platform/restapi/blob/master/build.gradle#L128

"responseView" method parameter for entity create and update operations

By default, entity create and update operation must return a result that contains just the following fields:

{
   "id": "<entityId>",
   "_entityName": "<entityName>",
   "_instanceName": "<intanceName>"
}

If other entity fields are required in the response, then an optional "responseView" query parameter must be passed in the request URL. In the case the creates/updated entity must be reloaded with this view and returned in the response JSON.

Updates

Breaking changes

Added optional parameter "responseView" for create/update request. Now, by default, only 3 parameters are passed in the response.

{
   "id": "<entityId>",
   "_entityName": "<entityName>",
   "_instanceName": "<intanceName>"
}

To disable this function, you must set the config cuba.rest.responseViewEnabled to false.

REST API: provide an option to include built-in views in method which returns entity views

Method for loading entity views does not return info about built-in views (_minimal, _base, _local). We can get built-in views separately using /metadata/entities/{entityName}/views/{viewName} but it will require many separate requests e.g. if you want to build correct deep graph for some complex view.
So it makes sense to introduce includeSystem flag which will return built-in views along with explicitly defined.

REST API: token revocation request with the wrong content type should returns the 400 Bad Request with the description

app/rest/v2/oauth/revoke request with the wrong content type returns the Internal Server Error with 500 code
The following exception appears in tomcat.log

org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'token' is not present
        at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:195) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:104) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) [servlet-api.jar:na]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [servlet-api.jar:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) [catalina.jar:8.5.9]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [catalina.jar:8.5.9]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.5.9]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [catalina.jar:8.5.9]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [catalina.jar:8.5.9]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]```

---
Original issue: https://youtrack.haulmont.com/issue/PL-9936

Merge sql scripts

Fix a problem with the migration of projects.

  1. Refresh create scripts
  2. Remove update scripts

REST-API: not-permitted entities serialization on service invocation

STR:

  1. Disable read of some entity (i.e. sec$User)

  2. Provide a method which loads these entities and expose it in REST API

    @Override
    public List<User> getUsers() {
        LoadContext<User> lc = new LoadContext<>(User.class);
        lc.setQueryString("select u from sec$User u");
        return dataManager.loadList(lc);
    }
  1. Invocation of the method from REST API returns list of entities but all attributes are stripped:
[
  {
    "_entityName": "sec$User",
    "_instanceName": "[]",
    "id": "12000811-36f9-9055-42bb-d2546c46e32a"
  }, {
    "_entityName": "sec$User",
    "_instanceName": "[]",
    "id": "09f10596-832f-2873-0968-05892effd3e5"
  }
]

Consider: not to strip attributes or do not return entities at all


Original issue: https://youtrack.haulmont.com/issue/PL-9272

REST API: Login is performed twice when a new access token is obtained

See: cuba-platform/cuba#2277

Environment

  • Platform version: 6.10.10

Description of the bug

  • Obtain a new REST API access token (http://localhost:8080/app/rest/v2/oauth/token)
  • In the log you'll see that login was performed twice:
01:42:12.406 INFO  c.h.c.s.a.AuthenticationManagerBean     - Logged in: 24668c0b-ce4d-a14c-da21-27ff4adb7735 [admin]
01:42:16.460 INFO  c.h.c.s.a.AuthenticationManagerBean     - Logged in: 78e5c771-47cf-bc42-2e69-9a35d391ed28 [admin]
01:42:17.419 INFO  c.h.r.auth.ClientProxyTokenStore        - REST API access token stored: [9265540714] ***-9c786317e72d

The error is probably caused by the issue cuba-platform/cuba#2045

Forum topic: https://www.cuba-platform.com/discuss/t/custom-portal-rest-api-failure-after-platform-upgrade/9571

Error creating SingleWAR

Environment

  • Platform version: 7.1-SNAPSHOT

Description of the bug or enhancement

  1. Create singleWAR for restapi-addon
  2. Download singleWar to Tomcat
  3. Start a project

ER:
Successful start

AR:
INFO: Server initialization in [564] milliseconds ╨░╨┐╤А 18, 2019 11:23:54 AM org.apache.catalina.core.StandardService startInternal INFO: Starting service [Catalina] ╨░╨┐╤А 18, 2019 11:23:54 AM org.apache.catalina.core.StandardEngine startInternal INFO: Starting Servlet engine: [Apache Tomcat/9.0.14] ╨░╨┐╤А 18, 2019 11:23:55 AM org.apache.catalina.startup.HostConfig deployWAR INFO: Deploying web application archive [C:\Projects\Addons\restapi\deploy\tomcat\webapps\restapi.war] 11:24:06.505 INFO c.h.cuba.core.sys.AppComponents - Using app components: [com.haulmont.cuba] 11:24:06.559 INFO c.h.c.c.s.AbstractWebAppContextLoader - Loading app properties from classpath:com/haulmont/addon/restapi/web-app.properties 11:24:06.567 INFO c.h.c.c.s.AbstractWebAppContextLoader - Loading app properties from /WEB-INF/local.app.properties 11:24:08.299 ERROR c.h.c.c.s.AbstractWebAppContextLoader - Error initializing application org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [com/haulmont/cuba/web-spring.xml]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'cuba_DataManager' for bean class [com.haulmont.cuba.core.app.DataManagerBean] conflicts with existing, non-compatible bean definition of same name and class [com.haulmont.cuba.client.sys.DataManagerClientImpl] at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:419) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:224) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:195) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:257) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:128) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:94) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:133) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:636) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:521) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:95) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] at com.haulmont.cuba.core.sys.CubaClassPathXmlApplicationContext.<init>(CubaClassPathXmlApplicationContext.java:27) ~[cuba-global-7.1-SNAPSHOT.jar:7.1-SNAPSHOT] at com.haulmont.cuba.core.sys.AbstractAppContextLoader.createApplicationContext(AbstractAppContextLoader.java:90) ~[cuba-global-7.1-SNAPSHOT.jar:7.1-SNAPSHOT] at com.haulmont.cuba.core.sys.AbstractAppContextLoader.initAppContext(AbstractAppContextLoader.java:62) ~[cuba-global-7.1-SNAPSHOT.jar:7.1-SNAPSHOT] at com.haulmont.cuba.core.sys.AbstractWebAppContextLoader.contextInitialized(AbstractWebAppContextLoader.java:78) ~[cuba-global-7.1-SNAPSHOT.jar:7.1-SNAPSHOT] at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4663) [catalina.jar:9.0.14] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5131) [catalina.jar:9.0.14] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.14] at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:713) [catalina.jar:9.0.14] at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690) [catalina.jar:9.0.14] at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695) [catalina.jar:9.0.14] at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:978) [catalina.jar:9.0.14] at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1850) [catalina.jar:9.0.14] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_181] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_181] at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) [tomcat-util.jar:9.0.14] at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) [na:1.8.0_181] at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:773) [catalina.jar:9.0.14] at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:427) [catalina.jar:9.0.14] at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1577) [catalina.jar:9.0.14] at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309) [catalina.jar:9.0.14] at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) [catalina.jar:9.0.14] at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:424) [catalina.jar:9.0.14] at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:367) [catalina.jar:9.0.14] at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:934) [catalina.jar:9.0.14] at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:831) [catalina.jar:9.0.14] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.14] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1382) [catalina.jar:9.0.14] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1372) [catalina.jar:9.0.14] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_181] at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) [tomcat-util.jar:9.0.14] at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) [na:1.8.0_181] at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:907) [catalina.jar:9.0.14] at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262) [catalina.jar:9.0.14] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.14] at org.apache.catalina.core.StandardService.startInternal(StandardService.java:423) [catalina.jar:9.0.14] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.14] at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:933) [catalina.jar:9.0.14] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.14] at org.apache.catalina.startup.Catalina.start(Catalina.java:637) [catalina.jar:9.0.14] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181] at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:350) [bootstrap.jar:9.0.14] at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492) [bootstrap.jar:9.0.14] Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'cuba_DataManager' for bean class [com.haulmont.cuba.core.app.DataManagerBean] conflicts with existing, non-compatible bean definition of same name and class [com.haulmont.cuba.client.sys.DataManagerClientImpl] at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.checkCandidate(ClassPathBeanDefinitionScanner.java:348) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:286) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.parse(ComponentScanBeanDefinitionParser.java:90) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:74) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1366) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1352) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:179) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:149) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:96) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:513) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:393) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE] ... 58 common frames omitted ╨░╨┐╤А 18, 2019 11:24:08 AM org.apache.catalina.core.StandardContext startInternal SEVERE: One or more listeners failed to start. Full details will be found in the appropriate container log file ╨░╨┐╤А 18, 2019 11:24:08 AM org.apache.catalina.core.StandardContext startInternal SEVERE: Context [/restapi] startup failed due to previous errors ╨░╨┐╤А 18, 2019 11:24:08 AM org.apache.catalina.startup.HostConfig deployWAR INFO: Deployment of web application archive [C:\Projects\Addons\restapi\deploy\tomcat\webapps\restapi.war] has finished in [13┬а331] ms ╨░╨┐╤А 18, 2019 11:24:08 AM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-nio-8080"] ╨░╨┐╤А 18, 2019 11:24:08 AM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["ajp-nio-8009"] ╨░╨┐╤А 18, 2019 11:24:08 AM org.apache.catalina.startup.Catalina start INFO: Server startup in [13┬а419] milliseconds

REST API does not support entities with composite primary key

Since id of such entities is passed as object it's not possible to call some methods where id is used in path fragment

DELETE /entities/{entityName}/{entityId}
GET /entities/{entityName}/{entityId}
PUT /entities/{entityName}/{entityId}

Solution:
Represent composite key identifier as JSON string and apply base64 URL encoding.

Model:

@Entity(name = "ref$CompositeKeyEntity")
@Table(name = "REF_COMPOSITE_KEY")
public class CompositeKeyEntity extends BaseGenericIdEntity<EntityKey> {

    private static final long serialVersionUID = -2538345720324624741L;

    @EmbeddedId
    private EntityKey id;

    @Column(name = "NAME")
    private String name;  
}

@Embeddable
@MetaClass(name = "ref$EntityKey")
public class EntityKey extends EmbeddableEntity {

    @Column(name = "TENANT")
    private Integer tenant;

    @Column(name = "ENTITY_ID")
    private Long entityId;
}

Encoding sample:

  • JSON: {tenant : 1, entityId: 1}
  • Base 64: e3RlbmFudCA6IDEsIGVudGl0eUlkOiAxfQ==
  • GET /entities/ref$CompositeKeyEntity/e3RlbmFudCA6IDEsIGVudGl0eUlkOiAxfQ==

Original issue: https://youtrack.haulmont.com/issue/PL-9444

Rest API first class files support

Дать возможность послать вместе с графом сущностей соответствующие файлы для FileDescriptor.
Фронтенд разработчикам очень неудобно писать код разбивая загрузку файла в систему и коммит сущностей. Должна быть возможность послать всё вместе в один запрос.
Поддержать такое поведение для сервисов, чтобы можно было залить файл одновременно с вызовом метода сервиса. Думаю потребуется завести какой-то промежуточный тип для принимаемых файлов, которые ещё не в хранилище


Original issue: https://youtrack.haulmont.com/issue/PL-7720

Provide method to obtain entity search count

Description

Currently it's possible to obtain search result count by using returnCount parameter. However there are some cases when only count is needed.

Updates

Added a new endpoint /entities/{entityName}/search/count for GET and POST methods.

Introduce isNull entity search condition

Description

Introduce isNull entity search condition for Rest API Add-on.

Updates

Created a platform-independent enum RestFilterOp for the Rest API Add-on and added a new condition isNull.

Example:

  "filter": {
    "conditions": [
      {
        "property": "name",
        "operator": "isNull"
      }
    ]
  }
}

REST API: The 'Accept-Language' request header is ignored when middleware service is invoked

Environment

  • Platform version: 6.10.9

Description of the bug or enhancement

If the middleware service is invoked with the standard rest api and the Accept-Language header is set in the request, then it is expected that UserSession in the service implementation will have the corresponding locale. However, it doesn't.

The problem is that REST API filter sets the locale from the Accept-Language header to the UserInvocationContext:

UserInvocationContext.setRequestScopeInfo(sessionId, locale, null, null, null);

When the middleware service is invoked after that, this value is not used.

Forum: https://www.cuba-platform.ru/discuss/t/ignoriruetsya-accept-language-pri-poluchenii-access-tokena-s-pomoshhyu-refresh-tokena-cherez-rest-api/2926

Entity JSON returned by the REST API should display fields of nested entities that are cyclic dependencies

For example:
Notice how one of the nested books holds title but the other, which is the same book as the parent of author, does not.

[ // books
  {
    "id": "123",
    "_entityName": "book",
    "title": "Book cuba-platform/cuba#123",
    "author": {
      "id": "234",
      "_entityName": "author",
      "name": "James Person",
      "books": [
        { // note that this does not include "title"
          "id": "123",
          "_entityName": "book"
        },
        { // but this does
          "id": "456",
          "_entityName": "book",
          "title": "Book cuba-platform/cuba#456"
        }
      ]
    }
  }
]

Original issue: https://youtrack.haulmont.com/issue/PL-10398

REST API: support enum parameters in query configuration

Description

Motivation:

  • When working with entities enums are serialized as name constants while when using queries we are only able to pass enum id as parameter.
  • If there is a support for such parameters we'll be able to generate better UI (i.e droprown instead of simple field) in Polymer client.

Updates

Added ability to pass enum data type to query parameters.

Query:

<query name="getDriversByStatus" entity="ref$Driver" view="_local">
        <jpql><![CDATA[select u from ref$Driver u where u.status = :status]]></jpql>
        <params>
            <param name="status" type="com.haulmont.rest.demo.core.entity.DriverStatus"/>
        </params>
    </query>

GET-request:

http://localhost:8080/app/rest/v2/queries/ref$Driver/getDriversByStatus?status=ACTIVE

Headers:

Authorization: Bearer <access_token>
Content-Type: application/json

Original issue: https://youtrack.haulmont.com/issue/PL-8752

Add ability to dynamically define view similarly to GraphQL for REST get requests

Currently, it is not possible to describe the graph of data to be fetched via rest API on the fly (using not predefined views on the server side). To make it possible developers could define them in the body of a get request, similarly to how it is achieved with GraphQL.

To prevent DDos, ability to use such functionality should be restrictable on the role level.


Original issue: https://youtrack.haulmont.com/issue/PL-9991

JSON in responses for entity create and update operations should not contain not-persistent meta-properties

JSON in responses for entity create and update operations should not contain not-persistent attributes. Requests for entity read should return not-persistent attributes.
This should be done because of the following case.
There are a Debtor and a Case entities. The Case entity has a not-persistent property that relates to debtor property:

@Table(name = "DEBT_CASE")
@Entity(name = "debt$Case")
public class Case extends StandardEntity {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "DEBTOR_ID")
    protected Debtor debtor;

    @MetaProperty(related = "debtor")
    public String getNonPersistentDebtorTitle() {
        return debtor == null ? null : debtor.getTitle();
    }
}

Suppose we create or update the Case. We accidentally passed the "nonPersistentDebtorTitle" in JSON as well. The JSON has a reference to the Debtor.

{
   "number": "CASE-001",
   "nonPersistentDebtorTitle": "someValue",
   "debtor": {
      "id": "60885987-1b61-4247-94c7-dff348347f93"
   }
}

In this case, after the entity is commited by the DataManager, it is serialized using the EntitySerializationAPI. By default, non-persistent meta-properties are also serialized, so a property value is read during the serialization. But since the "debtor.title" property is not read, an UnfetchedAttributeException is thrown.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.