web-dev-qa-db-fra.com

Conversion de json en protobuf généré dynamiquement en Java

Compte tenu de la réponse JSON suivante:

{
    "id" : "123456",
    "name" : "John Doe",
    "email" : "[email protected]"
}

Et le fichier user.proto suivant:

message User {
    string id = 1;
    string name = 2;
    string email = 3;
}

Je voudrais avoir la possibilité de créer dynamiquement la classe de messages protobuf (compiler un fichier .proto au moment de l'exécution), de sorte que si la réponse json est améliorée avec un champ "phone" : "+1234567890", je pourrais simplement télécharger une nouvelle version du fichier protobuf contenir string phone = 4 et obtenir ce champ exposé dans la réponse protobuf, sans redémarrage du service.

Si je devais tirer ces classes d'un chapeau, j'aimerais pouvoir écrire quelque chose avec le code suivant. 

import com.googlecode.protobuf.format.JsonFormat;
import com.googlecode.protobuf.Message;
import org.Apache.commons.io.FileUtils;

...

public Message convertToProto(InputStream jsonInputStream){
    // get the latest user.proto file
    String userProtoFile = FileUtils.readFileToString("user.proto");

    Message userProtoMessage = com.acme.ProtobufUtils.compile(userProtoFile);
    Message.Builder builder = userProtoMessage.newBuilderForType(); 
    new JsonFormat().merge(inputStream, Charset.forName("UTF-8"), builder);
    return builder.build();
}

Existe-t-il une méthode existante com.acme.ProtobufUtils.compile (...)? Ou comment en implémenter un? L'exécution d'une classe de protocole + charge semble excessive, mais je suis prêt à l'utiliser si aucune autre option n'est disponible ... 

12
Alin Stoian

Vous ne pouvez pas compiler le fichier .proto (du moins pas en Java), mais vous pouvez précompiler le .proto dans un descripteur .desc

protoc --descriptor_set_out=user.desc user.proto

puis utilisez l'analyseur DynamicMessage:

DynamicMessage.parseFrom(Descriptors.Descriptor type, byte[] data)

Source: Google Groupes de discussion

3
MaanooAk