java - Google Cloud Endpoints client libraries generation duplicates entities -


i've found strange behavior when generate client libraries endpoints.

in appengine project, have 2 endpoint classes handles operations 2 entities:

groupendpoint entity group

contactendpoint entity contact

the group entity has list of contacts, because when api method of groupendpoint called, have update contacts.

the problem when generate client libraries, contact entity generated in 2 different namespaces (one each endpoint), quite confusing, because end same class (exactly same) twice.

here example:

group.java

package backend;  import java.util.list;  import javax.jdo.annotations.idgeneratorstrategy; import javax.jdo.annotations.persistencecapable; import javax.jdo.annotations.persistent; import javax.jdo.annotations.primarykey;  @persistencecapable public class group {     @primarykey     @persistent(valuestrategy = idgeneratorstrategy.identity)     private long id;      @persistent     private list<contact> contactlist;      public long getid() {         return id;     }      public void setid(long id) {         this.id = id;     }      public list<contact> getcontactlist() {         return contactlist;     }      public void setcontactlist(list<contact> contactlist) {         this.contactlist = contactlist;     } } 

groupendpoint.java (dummy code example)

package backend;  import com.google.api.server.spi.config.api; import com.google.api.server.spi.config.apimethod; import com.google.api.server.spi.response.collectionresponse;  import javax.annotation.nullable; import javax.inject.named;  @api(name = "groupendpoint") public class groupendpoint {      @apimethod(name = "listcontact")     public collectionresponse<group> listgroup(             @nullable @named("cursor") string cursorstring,             @nullable @named("limit") integer limit) {         return null;     } } 

contact.java

package backend;  import javax.jdo.annotations.idgeneratorstrategy; import javax.jdo.annotations.persistencecapable; import javax.jdo.annotations.persistent; import javax.jdo.annotations.primarykey;  @persistencecapable public class contact {      @primarykey     @persistent(valuestrategy = idgeneratorstrategy.identity)     private long id; } 

contactendpoint.java (dummy code example)

package backend;  import com.google.api.server.spi.config.api; import com.google.api.server.spi.config.apimethod; import com.google.api.server.spi.config.apinamespace; import com.google.api.server.spi.response.collectionresponse;  import javax.annotation.nullable; import javax.inject.named;  @api(name = "contactendpoint") public class contactendpoint {      @apimethod(name = "listcontact")     public collectionresponse<contact> listcontact(             @nullable @named("cursor") string cursorstring,             @nullable @named("limit") integer limit) {         return null;     } } 

build.gradle

// currently, appengine gradle plugin's appengine devappserver launch doesn't interact intellij/androidstudio's // gradle integration.  temporary solution, please launch command line. // ./gradlew modulename:appenginerun // if more information on gradle-appengine-plugin please refer github page // https://github.com/googlecloudplatform/gradle-appengine-plugin  buildscript {     repositories {         mavencentral()     }     dependencies {         classpath 'com.google.appengine:gradle-appengine-plugin:1.9.1'     } }  repositories {     mavencentral(); }  apply plugin: 'java' apply plugin: 'war' apply plugin: 'appengine'  sourcecompatibility = 1.7 targetcompatibility = 1.7  dependencies {   appenginesdk 'com.google.appengine:appengine-java-sdk:1.9.1'   compile 'javax.servlet:servlet-api:2.5'     compile 'com.google.appengine:appengine-endpoints:1.9.1'     compile 'com.google.appengine:appengine-endpoints-deps:1.9.1'     compile 'javax.servlet:servlet-api:2.5'     compile 'org.datanucleus:datanucleus-core:3.2.13'     compile 'org.datanucleus:datanucleus-api-jpa:3.2.3'     compile 'javax.jdo:jdo-api:3.0.1'     compile 'org.datanucleus:datanucleus-api-jdo:3.2.8'     compile 'org.datanucleus:datanucleus-jdo-query:3.0.2'     compile 'com.google.appengine.orm:datanucleus-appengine:2.1.2'     compile 'org.apache.geronimo.specs:geronimo-jpa_2.0_spec:1.1'     compile 'com.ganyo:gcm-server:1.0.2'     compile 'net.sf.javaprinciples.persistence:persistence-api:4.0.0' }  appengine {   downloadsdk = true   appcfg {     oauth2 = true   } } 

when generate client libraries, creates groupendpoint-v1-java.zip , contactendpoint-v1-java.zip in build directory. if extract these files see each zip file have contact class.

for groupendpoint-v1-java.zip:

/*  * licensed under apache license, version 2.0 (the "license"); may not use file except  * in compliance license. may obtain copy of license @  *  * http://www.apache.org/licenses/license-2.0  *  * unless required applicable law or agreed in writing, software distributed under license  * distributed on "as is" basis, without warranties or conditions of kind, either express  * or implied. see license specific language governing permissions , limitations under  * license.  */ /*  * code generated https://code.google.com/p/google-apis-client-generator/  * (build: 2014-04-15 19:10:39 utc)  * on 2014-04-22 @ 12:22:19 utc   * modify @ own risk.  */  package com.appspot.myapplicationid.groupendpoint.model;  /**  * model definition contact.  *  * <p> java data model class specifies how parse/serialize json  * transmitted on http when working groupendpoint. detailed explanation see:  * <a href="http://code.google.com/p/google-http-java-client/wiki/json">http://code.google.com/p/google-http-java-client/wiki/json</a>  * </p>  *  * @author google, inc.  */ @suppresswarnings("javadoc") public final class contact extends com.google.api.client.json.genericjson {    @override   public contact set(string fieldname, object value) {     return (contact) super.set(fieldname, value);   }    @override   public contact clone() {     return (contact) super.clone();   }  } 

for contactendpoint-v1-java.zip:

/*  * licensed under apache license, version 2.0 (the "license"); may not use file except  * in compliance license. may obtain copy of license @  *  * http://www.apache.org/licenses/license-2.0  *  * unless required applicable law or agreed in writing, software distributed under license  * distributed on "as is" basis, without warranties or conditions of kind, either express  * or implied. see license specific language governing permissions , limitations under  * license.  */ /*  * code generated https://code.google.com/p/google-apis-client-generator/  * (build: 2014-04-15 19:10:39 utc)  * on 2014-04-22 @ 12:22:21 utc   * modify @ own risk.  */  package com.appspot.myapplicationid.contactendpoint.model;  /**  * model definition contact.  *  * <p> java data model class specifies how parse/serialize json  * transmitted on http when working contactendpoint. detailed explanation see:  * <a href="http://code.google.com/p/google-http-java-client/wiki/json">http://code.google.com/p/google-http-java-client/wiki/json</a>  * </p>  *  * @author google, inc.  */ @suppresswarnings("javadoc") public final class contact extends com.google.api.client.json.genericjson {    @override   public contact set(string fieldname, object value) {     return (contact) super.set(fieldname, value);   }    @override   public contact clone() {     return (contact) super.clone();   }  } 

note difference belong different namespaces. confusing when i'm using client libraries.

how can avoid behavior?

thanks.

i having same problem , figured out way of solving this. may have advantages , restrictions present them here.

you having different models (on client side) because in different libs. example, contact list in libcontactendpoint , libgroupendpoint, since contact class used in both.

in order have 1 class representing entity on client side, you'll need keep in 1 endpoint (in client project). so, 1 way that, using @api annotation. annotation used in endpoint classes. so, if class groupendpoint has @api(name = "groupendpoint"), libgroupendpoint created. if want both contact , group in same endpoint, without duplications, endpoint classes must point same api. solution:

package backend;  import com.google.api.server.spi.config.api; import com.google.api.server.spi.config.apimethod; import com.google.api.server.spi.response.collectionresponse;  import javax.annotation.nullable; import javax.inject.named;  //changing api name @api(name = "generalendpoint") public class groupendpoint {      @apimethod(name = "listcontact")     public collectionresponse<group> listgroup(             @nullable @named("cursor") string cursorstring,             @nullable @named("limit") integer limit) {         return null;     } } 

contactendpoint have generalendpoint (you can use name condition equal).

package backend;  import com.google.api.server.spi.config.api; import com.google.api.server.spi.config.apimethod; import com.google.api.server.spi.config.apinamespace; import com.google.api.server.spi.response.collectionresponse;  import javax.annotation.nullable; import javax.inject.named;  @api(name = "generalendpoint") public class contactendpoint {      @apimethod(name = "listcontact")     public collectionresponse<contact> listcontact(             @nullable @named("cursor") string cursorstring,             @nullable @named("limit") integer limit) {         return null;     } } 

now, won't have problem. however, remember now, in client side, instead of using groupendpoint or contactendpoint operations , call endpoint methods, must use generalenpoint.

disadvantage:

  1. all methods of classes point same @api in same class after generation of cloud endpoint library
  2. methods in classes point same @api (but different classes in java) can not have same name @apimethod(name = "nameofmethod")

the 1 not important because don't edit library, call method. 2nd requires attention when creating methods across classes in app engine project.


Comments

Popular posts from this blog

windows - Single EXE to Install Python Standalone Executable for Easy Distribution -

c# - Access objects in UserControl from MainWindow in WPF -

javascript - How to name a jQuery function to make a browser's back button work? -