Tango Feature Request 4: Defining a standard Tango REST API

Hi Igor,

  • Every device has a black-box which registers all the calls the device receive. There is a method in the DeviceProxy
  • class allowing a client to get the content of this black-box. But may be it is not important and does not need to be seen in the RESTfull API
  • The call set_attribute_config() allows a client to set the attribute configuration (its modifiable part). For instance, this
  • allows a client to change the alarm threshold or the attribute label or … This is what ATKpanel is using when you click on the button labelled with … close to attribute value display
  • The history related calls (read_attribute_history or command_inout_history) are when your attribute (or command) is polled. In this case, you have a buffer for each polled
  • object managed as a round-robin buffer. These calls allow the user to retrieve this buffer content (therefore a brief history of the attribute value). Could be useful in a trend window for instance.
  • The write_read_attribute(s) calls is something like a write_attribute(s) followed by a read_attribute(s) on a device in a
  • single call. If you use the default device serialisation mode, it is atomic (not the case if you do a write followed by a read)

Cheers

Emmanuel
Hi All,

I have added pipes to the API.

Manu
  • The call set_attribute_config() allows a client to set the attribute configuration (its modifiable part). …

For now we can just say that this must be visible in an admin panel (I suppose every implementation of the API provides one, where an authorized user can set implementation specific settings, like cache policy etc).

History related calls we can add in later releases, if there will a demand.

Let's say that PUT is implementation depended, i.e. write_read or write then read.

Concerning w_value. For me it seems very hardware specific and I think we must leave it on the Tango level. Since we now develop a very high level API which may be used by completely new users with web development background, w_value is quite misleading.

From what I have understood client may always cache it's own value. Consider this JS snippet:



var w_value = 42;

doPUT(w_value, {
   onSuccess: function(response){ //suppose Tango returns 23
      alert(w_value); //42
      alert(response.value); //23
      //…
   }
});

In my opinion with this API we must force users to use this idiom when dealing with slow hardware:

    1. attempt to write 2. poll or subscribe to state change, i.e. wait while MOVING or RUNNING 3. read actual value 4. check correctness

this requires server side support as well - correct usage of states, but this we also must force.

Note: I also keep in mind analog-to-digital hardware, i.e. when one writes 3,0 but gets 2,97 or 3,04. This must be handled in the 4th step.

Of course it can be added later it if there will be a strong demand.

BTW is it accessible in Java API?
Edited 8 years ago
Hi,

The first implementation of the Tango REST API RC1 is here.

There is also a new project has been started on the bitbucket: https://bitbucket.org/Ingvord/tango-rest-api/wiki/Home

This project is dedicated to API specification. So if you want to add something to the specification you are welcome to open a new enhancement. Here is an example of such issue.

Wiki itself is an repo so you can clone it and edit (perhaps you will need a bitbucket account to clone it). All the changes are visible, if you press history button in the right top corner.

Project itself will be a maven java project with compatibility tests. I plan to add some next week.

Issues related to the implementation go here.

Cheers,
Hi,

Few simple tests were added. Everyone can now validate his Tango REST API implementation against the spec:


$> hg clone https://bitbucket.org/Ingvord/tango-rest-api 
destination directory: tango-rest-api
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 2 changes to 2 files
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$> cd tango-rest-api
$> mvn clean test -Dtango.rest.url=http://localhost:8080/hzgcttest/rest -Dtango.rest.auth.method=basic -Dtango.rest.user={user} -Dtango.rest.password={password}

[INFO] Scanning for projects…
[…]
Tests run: 13, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.518 sec

Results :

Tests run: 13, Failures: 0, Errors: 0, Skipped: 0

[INFO] ————————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————————
[INFO] Total time: 3.289 s
[INFO] Finished at: 2015-12-17T18:40:41+01:00
[INFO] Final Memory: 14M/490M
[INFO] ————————————————————————
$> ^_^
Edited 8 years ago
Hi All,

The Tango REST API spec has been updated to version rc2 [Release Candidate 2]:

1) In the PUT request to Pipes data type is added [#1]
2) Command/Attribute history resource is added [#6&#7]
3) GET, PUT, DELETE methods for an attribute's property [#3]
4) PUT method for the attribute's info [#5]

*) Numbers in the square brackets are issues numbers in the tracker

Tests and the implementation will be updated soon.

Regards,
Hi Igor,

Sounds good I will try soon this rc2.

/Vincent
Vincent Hardion
Control System
MAX IV Laboratory
Hi,

mTangoREST.server-rc2-0.2 has been released!!!

It now supports rc2 API spec, embeds tomcat server and is distributed as a single executable jar file, i.e.


java -jar mtango.server-rc2-0.2.jar test

starts Tango device with embedded REST server.

For tomcat geeks war file is also available.

Getting started documentation is located here.

REST API test suite has been also updated to rc2.

Have a nice weekend!

Regards,

Edited 8 years ago
Hi Igor,

I have some problem running mTango rc2
HTTP Status 500 - java.lang.NullPointerException

type Exception report

message java.lang.NullPointerException

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException
	org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:247)
	org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:149)
	org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:432)
	org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:376)
	org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179)
	org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)
	org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
	org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	org.tango.web.server.filters.SimpleCacheFilter.doFilter(SimpleCacheFilter.java:37)
	org.tango.web.server.filters.TimeWatcher.doFilter(TimeWatcher.java:28)

root cause

java.lang.NullPointerException
	org.tango.web.server.providers.AbstractCacheProvider.filter(AbstractCacheProvider.java:35)
	org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:122)
	org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:49)
	org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:427)
	org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:376)
	org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179)
	org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)
	org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
	org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	org.tango.web.server.filters.SimpleCacheFilter.doFilter(SimpleCacheFilter.java:37)
	org.tango.web.server.filters.TimeWatcher.doFilter(TimeWatcher.java:28)

note The full stack trace of the root cause is available in the Apache Tomcat/8.0.33 logs.
Apache Tomcat/8.0.33

I am using Centos 7 with with rpms from Max IV public repo: http://pubrepo.maxiv.lu.se/rpm/el7/x86_64/

Best regards,
Lukasz
Kind Regards,
Lukasz Zytniak

Control Software Engineer
—————————————————————
Edited 7 years ago
Hi Lukasz,

Thank you for reporting the problem. A ticket has been created: 101

Try to use rc2-0.3. I fixed some NPEs in the newer version. Hopefully these are the same.

If not I need more info. Could you please attach full Tomcat's log and possibly log from your browser? For instance, in firefox there is a developer console which shows net activity. Does it happen all the time or just for a specific request? Basically I need context in which NPE is happening, i.e. request data, to investigate the problem

Thank you in advance.

Regards,
Hi Igor,
I tried the last release candidate. It looks like the WAR assumes that the Database server is sys/database/2. Is it possible to configure this value ?

At SOLEIL, our systems are deployed with database server named sys/database/dbds1 and sys/database/dbds2

thanks for your work and your help.

Greg

TRACE 09-05-2016 10:03:57 [localhost-startStop-1 - o.t.c.e.p.DeviceProxyWrapper] DeviceProxyWrapper(sys/database/2)
DEBUG 09-05-2016 10:03:57 [localhost-startStop-1 - o.t.c.e.p.DeviceProxyWrapper] Failed to construct DeviceProxyWrapper for device sys/database/2
ERROR 09-05-2016 10:03:57 [localhost-startStop-1 - o.t.w.s.Launcher] MTango has failed to initialize: sys/database/2:DB_DeviceNotDefined[device sys/database/2 not defined in the database   calypso.synchrotron-soleil.fr:20001 !]
Edited 7 years ago
 
Register or login to create to post a reply.