Home | About | Sematext search-lucene.com search-hadoop.com
NEW: Monitor These Apps!
elasticsearch, apache solr, apache hbase, hadoop, redis, casssandra, amazon cloudwatch, mysql, memcached, apache kafka, apache zookeeper, apache storm, ubuntu, centOS, red hat, debian, puppet labs, java, senseiDB
 Search Hadoop and all its subprojects:

Switch to Threaded View
Avro >> mail # user >> How to add optional new record fields and/or new methods in avro-ipc?


Copy link to this message
-
Re: How to add optional new record fields and/or new methods in avro-ipc?
On 10/13/11 5:25 AM, "常冰琳" <[EMAIL PROTECTED]> wrote:

> Hi,
> I try to use avro-ipc in my project and got a problem, if the server side
> needs to upgrade,
> add a few optional field to Request/Response object, or add a new method, thus
> change the
> schema.
> I use reflect, add a new String field in Request class with @Nullable in
> server side, keep client
> side unchanged, but it won't to work.
> I think protobuf supports this, just by adding new optional fields.
> So does it possible or how to support backward compatibility in other way?

>
This should work in general.  An avro field can be promoted from a String to
a nullable String.  The inverse is not true.  A client that is expecting a
non-nullable string field response cannot read data serialized with a
nullable string.  

I am not familiar enough with the Protocol requestor or how it interacts
with the Reflect API to spot the issue.  I can't tell from the stack trace
if a resolving decoder is in use — which is required to resolve from one
schema to another.

If you want the server side to evolve you can:
add new fields
remove fields (only if the field has a default on the client side)
promote fields as permitted (int -> long; string -> nullable string; etc.)
rename fields or other named types with aliases.

> Here is the protocol class
>
>
> old:
>
>
>
> public interface SampleService {
>   public static class Request {
>     int id;
>     String name;
>     @Nullable
>     String address;
>
>     public Request() {
>       this(0, "null", null);
>     }
>
>     public Request(int id, String name, String address) {
>       this.id <http://this.id>  = id;
>       this.name <http://this.name>  = name;
>       this.address = address;
>     }
>
>     public int getId() {
>       return id;
>     }
>
>     public String getName() {
>       return name;
>     }
>
>     public String getAddress() {
>       return address;
>     }
>    
>   }
>  
>   public static class Response {
>     @Nullable
>     String value;
>
>     public Response() {
>       this("null");
>     }
>     public Response(String value) {
>       this.value = value;
>     }
>
>     public String getValue() {
>       return value;
>     }
>   }
>
>   int fibonacci(int n);
>   int sum(int [] nums, int base);
>   Response complexCall(Request req);
> }
>
>
>
>
> new:
>
>
> public interface SampleService {
>   public static class Request {
>     int id;
>     String name;
>     @Nullable
>     String address;
>     @Nullable
>     String address2;
>
>     public Request() {
>       this(0, "null", null, null);
>     }
>
>     public Request(int id, String name, String address, String address2) {
>       this.id <http://this.id>  = id;
>       this.name <http://this.name>  = name;
>       this.address = address;
>       this.address2 = address2;
>     }
>
>     public int getId() {
>       return id;
>     }
>
>     public String getName() {
>       return name;
>     }
>
>     public String getAddress() {
>       return address;
>     }
>
>     public String getAddress2() {
>       return address2;
>     }
>    
>   }
>  
>   public static class Response {
>     @Nullable
>     String value;
>
>     public Response() {
>       this("null");
>     }
>     public Response(String value) {
>       this.value = value;
>     }
>
>     public String getValue() {
>       return value;
>     }
>   }
>
>   int fibonacci(int n);
>   int sum(int [] nums, int base);
>   Response complexCall(Request req);
> }
>
>
> Here is the error message:
>
> Exception in thread "main" org.apache.avro.AvroRuntimeException:
> org.apache.avro.AvroTypeException: Found {
>   "type" : "record",
>   "name" : "Request",
>   "namespace" : "com.mycompany.app.SampleService$",
>   "fields" : [ {
>     "name" : "id",
>     "type" : "int"
>   }, {
>     "name" : "name",
>     "type" : "string"
>   }, {
>     "name" : "address",
>     "type" : [ "null", "string" ]
>   } ]
> }, expecting {
>   "type" : "record",
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908>
)
NEW: Monitor These Apps!
elasticsearch, apache solr, apache hbase, hadoop, redis, casssandra, amazon cloudwatch, mysql, memcached, apache kafka, apache zookeeper, apache storm, ubuntu, centOS, red hat, debian, puppet labs, java, senseiDB