Code Monkey home page Code Monkey logo

ez-tango-api's Introduction

ezTangoAPI - Simple (ez = easy) Tango Java Client API

codebeat badge

Download

This library provides simplified client API for JTango

Why simplified? Compare these two code snippets:

//Pure TangORB
    DeviceProxy proxy = new DeviceProxy("tango://whatever:10000/sys/tg_test/1");
    DeviceAttribute attribute = proxy.read_attribute("double_scalar");
    if(result.hasFailed()){
        throw new Exception("Can not read attribute.");
    }
    int dataFormat = result.getDataFormat()
    int dataType = result.getType()
    double result;
    switch(dataType){
        case Tango_DEV_Double:
            switch(dataFormat){
                case _SCALAR:
                    result = attribute.extractDouble()
                ...
            }
        ...
    }
    ...

//VS

//ezTangORB
    TangoProxy proxy = TangoProxies.newDeviceWrapper("tango://whatever:10000/sys/tg_test/1");
    double result = proxy.<Double>readAttribute("double_scalar");
    ...

Getting started

  1. Add the following repository to your settings.xml or pom.xml:
<repositories>
  <repository>
    <id>hzg-bintray</id>
    <url>http://dl.bintray.com/hzgde/hzg-wpn-projects</url>
    <releases>
      <enabled>true</enabled>
    </releases>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
  </repository>
</repositories>
  1. Add the following dependency to your pom.xml:
    <dependency>
        <groupId>org.tango</groupId>
        <artifactId>ezTangORB</artifactId>
        <version>1.1.7</version>
    </dependency>

How to use

In the code create a TangoProxy instance using one of the factory methods of the TangoProxies class:

TangoProxy proxy = TangoProxies.newDeviceProxyWrapper("tango://whatever:10000/sys/tg_test/1");

//OR

//This creates interface specific Tango proxe. See below for more details
SomeTangoServer proxy = TangoProxies.newTangoProxy("tango://whatever:10000/domain/some/0",SomeTangoServer.class);

Read/Write attributes

//simply read attribute value
T data = proxy.readAttribute("some_attr");//may throw ClassCastException if return value does not match T

//read attribute value and time
Map.Entry<T,long> data_time = proxy.readAttributeValueTime("some_attr");

//read attribute value,time and quality
Triplet<T,long,Quality> data_time_quality = proxy.readAttributeValueTimeQuality("some_attr");

//write attribute
T data =  ...;
proxy.writeAttribute("some_attr_w",data);//may throw ClassCastException if return value does not match T

Execute commands

T input = ...;
V output = proxy.executeCommand("some_cmd",input);//may throw ClassCastException

Handle events

Currently AttrConfig and DataReady events are not supported. Use standard TangORB API if you need them.

//1st you need to subscribe to an event
TangoEvent event = TangoEvent.CHANGE;//.USER,.ARCHIVE,.PERIODIC
proxy.subscribeToEvent("some_attr",event);

//then you can add a number of listeners to the subscription
TangoEventListener listener = new TangoEventListener(){
    public void onEvent(data){...}
    public void onError(error){...}
}
//user must keep reference to this listener. See explanation below
proxy.addListener("some_attr",event,listener);

//...

//finally unsubscribe
proxy.unsubscribeFromEvent("some_attr",event);

Here is a small explanation:

Implementation of the TangoProxy guarantees the following - a subscription to an event will be performed only once during the first call of the TangoProxy#subscribeToEvent method. This creates a single instance of ITangoWhateverListner, for instance, ITangoChangeListener with an empty list of user defined listeners.

User adds then listeners to this single tango event listener (TangoProxy.addListener). Effectively a response from Tango event system is forwarded to these listeners. So adding and removing listeners does not invoke network call to the remote Tango. These listeners are stored in a weakly tight list to prevent memory leaks. Therefore user must keep reference to the listeners all the time they are needed.

All this is done to prevent extensive communication when a large number of threads try to subscribe to an event.

Summarizing - subscribe to the event in intialization phase. You may add any number of temporary listener objects during the execution phase. All unused isteners will be automatically removed.

Standard TangORB API

Since ezTangORB is just a Façade on top of TangORB you may use the standard API as well:

fr.esrf.tango.DeviceProxy deviceProxy = proxy.toDeviceproxy();

fr.esrf.tango.TangoEventsAdapter eventsAdapter = proxy.toTangoEventsAdapter();

Interface Specific proxy

Users may also use interface specific proxy. For instance, lets say we have some device described by this interface:

//vendor provides this interface in a dedicated jar file
public interface SomeTangoDevice extends TangoProxy {

     int getIntAttr();

     void someCommand(int[] args);

}

Now we can create its proxy:

import org.vendor.SomeTangoDevice;
//...

SomeTangoDevice device = TangoProxies.newTangoProxy("tango://whatever:10000/sys/some/0",SomeTangoDevice.class);

and execute commands or read attributes like this:

int attrValue = device.getIntAttr();

device.someCommand(new int[]{1,2,3});

Thread safety

TangoProxy implementation guarantees thread-safety for its methods.

ez-tango-api's People

Contributors

ingvord avatar

Watchers

 avatar  avatar  avatar

ez-tango-api's Issues

NPE must be a NotAvailable or whatever pointing out a real reason

Original report by me.


This happens when remote server is not started:

java.lang.NullPointerException
	org.tango.client.ez.proxy.DeviceProxyWrapper.executeCommand(DeviceProxyWrapper.java:224)
	org.tango.web.server.AccessControl.getAccess(AccessControl.java:51)
	org.tango.web.server.AccessControl.checkUserCanRead(AccessControl.java:40)
	org.tango.web.server.filters.AccessControlFilter.doFilter(AccessControlFilter.java:37)

DeviceProxyWrapper#hasAttributealways returns false

Original report by Ingvord (Bitbucket: Ingvord, GitHub: Ingvord).


subj

The problem is in method impl

#!java


    public boolean hasAttribute(String attrName) {
        TangoAttributeInfoWrapper attrInf = attributeInfo.get(attrName);

must be

#!java
public boolean hasAttribute(String attrName) {
        TangoAttributeInfoWrapper attrInf = getAttributeInfo(attrName);

As a workaround users must call getAttributeInfo before hasAttribute

Non-user-friendly NPE

Original report by Ingvord (Bitbucket: Ingvord, GitHub: Ingvord).


wpn.hdri.tango.proxy.TangoProxyException: java.lang.NullPointerException
	at wpn.hdri.tango.proxy.DeviceProxyWrapper.executeCommand(DeviceProxyWrapper.java:254)
	at hzg.wpn.mtango.DatabaseDs.getDeviceAddress(DatabaseDs.java:30)
	at hzg.wpn.mtango.DatabaseDsTest.testGetDeviceAddress(DatabaseDsTest.java:15)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
Caused by: java.lang.NullPointerException
	at wpn.hdri.tango.proxy.DeviceProxyWrapper.executeCommand(DeviceProxyWrapper.java:248)
	... 23 more

Happens when TangoDataType is null

proxy#getAttributeInfo should throw exception, ver. 1.9

Original report by Ingvord (Bitbucket: Ingvord, GitHub: Ingvord).


Consider the following:

public boolean isArrayAttribute(String attrName) throws ClientException {
            TangoAttributeInfoWrapper attributeInfo = proxy.getAttributeInfo(attrName);
            return SpectrumTangoDataFormat.class.isAssignableFrom(attributeInfo.getFormat().getClass());
    }

This leads to an NPE with current implementation (attributeInfo == null) and it is not clear whether it is safe to return false. So user is forced to throw exception anyway.

Implement interface specific proxy

Original report by Ingvord (Bitbucket: Ingvord, GitHub: Ingvord).


The goal is:

SomeTangoDevice device = TangoProxy.proxy("sys/some/0",SomeTangoDevice.class);

device.someMethod();

device.getAttr1();

Of course users now must obtain the Class instance of the device somehow. One possibility is to generate it when server is being deployed.

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.