2

I output a POJO from an azure function written with spring cloud function which contains a datetime type. I have tried it with instant where it was treated as a POJO:

  "timestamp": {
    "seconds": 1584229103,
    "nanos" 0
  }

I tried it as an OffsetDateTime and got:

  "timestamp": {
    "dateTime": {
      "date": {
        "year": 1970,
        "month": 1,
        "day": 19
      },
      "time": {
        "hour": 8,
        "minute": 3,
        "second": 46,
        "nano": 837000000
      }
    },
    "offset": {
      "totalSeconds": 0
    }
  }

I tried various things at the spring level like:

    @Bean
    public MappingJackson2MessageConverter configJacksonMessageConverter() {
        final MappingJackson2MessageConverter mappingJackson2MessageConverter = new MappingJackson2MessageConverter();
        ObjectMapper objectMapper = new ObjectMapper()
                .registerModule(new JavaTimeModule());
        mappingJackson2MessageConverter.setObjectMapper(objectMapper);
        return mappingJackson2MessageConverter;
    }

But they had no effect. Reading https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-java#pojos it sounds like azure-functions-java-worker is doing the final work of converting the pojo to json and it doesn't use jackson at all. How do I get a similar output to JavaTimeModule with automatic serialisation of values? Do I have to work with string outputs? I could find no documentation dealing with this and no examples.

Razneesh
  • 1,147
  • 3
  • 13
  • 29
dashambles
  • 529
  • 8
  • 22

1 Answers1

1

There are unfortunatelly several layers ...

  • spring cloud functions using jackson (and handles java.time.* correctly by default)
    • currently bugged
  • azure functions runtime (azure-function-java-worker) using gson
    • currently bugged

(things are getting even more complicated when you use more libraries like spring cosmos db which need to serialize for their purposes. This library is wrapper around ms-cosmos-db which has its own jackson instance / independent on spring instance. They are working on it ... )

Yeah, I fight it as well... without much success.

I was able to control it with

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.time.Instant;
import java.time.format.DateTimeFormatter;

public class InstantGsonAdapter extends TypeAdapter<Instant> {

    @Override
    public void write(JsonWriter out, Instant value) throws IOException {
        out.value(DateTimeFormatter.ISO_INSTANT.format(value));
    }

    @Override
    public Instant read(JsonReader in) throws IOException {
        return Instant.parse(in.nextString());
    }
}

But it stopped working ... and I do not yet investigated why... Probably because I tried to fixed/workaround another bug from another layer. Or because I upgraded yesterday )-:

Tip: be carefull what are you testing... whether you run Spring cloud function app and calling it. Or you run azure runtime (mvn azure-functions:run) and calling it... Usually, spring tests calls the first.

(I will try to find and post related bugs ... I am not able now, sorry)

Wooff
  • 1,091
  • 12
  • 23