поля даты преобразуются в другой формат, когда объект Java сохраняется в эластичном поиске?

Привет, у меня есть Java-приложение с весенней загрузкой, и я пытаюсь интегрировать в него возможности эластичного поиска. Я написал тест junit, в котором я запускаю встроенный эластичный поиск, затем я читаю файл json, содержащий массив объектов json, а затем пытаюсь чтобы вставить этот объект в эластичный поиск как документ под индексом.

Однако проблема в том, что когда я вставляю объект Java, содержащий поле Instant, я теряю формат.

история сообщениярепортингресаурцеинттест

@RunWith(SpringRunner.class)
@SpringBootTest(classes = PrimecastApp.class)
public class MessageHistoryReportingResourceIntTest {
    @Autowired
    private MessageHistoryReportingService messageHistoryReportingService;

    @Autowired
    private HttpMessageConverter[] httpMessageConverters;

    @Autowired
    private ExceptionTranslator exceptionTranslator;

    @Value("${elasticsearch.configuration.host}")
    private String host;

    @Value("${elasticsearch.configuration.port}")
    private int port;

    private MockMvc restMvc;

    private EmbeddedElastic embeddedElastic;

    private RestHighLevelClient client;

@Before
    public void startElasticServer() {

        try {
            embeddedElastic = EmbeddedElastic.builder().withElasticVersion("6.6.1")
                    .withSetting(PopularProperties.HTTP_PORT, port)
                    .withSetting(PopularProperties.CLUSTER_NAME, "my_cluster").withStartTimeout(5, TimeUnit.MINUTES)
                    .build()
                    // .withIndex("mep-report-today",
                    // IndexSettings.builder().withType("mep-report-mapping.json",
                    // getJsonResourceAsStream1()).build()).build()
                    .start();

            client = new RestHighLevelClient(RestClient.builder(new HttpHost(host, port, "http")));

            ObjectMapper objMapper = new ObjectMapper();
            objMapper.registerModule(new JavaTimeModule());

            List<MessageHistory> messageHistories = objMapper.readValue(getMessageHistoryResourceAsStream(),
                    objMapper.getTypeFactory().constructCollectionType(List.class, MessageHistory.class));
            BulkRequest request = new BulkRequest();

            for (int i = 0; i < messageHistories.size(); i++) {

                request.add(new IndexRequest("mep-report-today", "doc", String.valueOf(i))
                        .source(objMapper.writeValueAsString(messageHistories.get(i)), XContentType.JSON));

            }
            request.timeout(TimeValue.timeValueMinutes(5));

            BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);

            MockitoAnnotations.initMocks(this);

            MessageHistoryReportingResource messageHistoryReportingResource = new MessageHistoryReportingResource(
                    messageHistoryReportingService);

            this.restMvc = MockMvcBuilders.standaloneSetup(messageHistoryReportingResource)
                    .setMessageConverters(httpMessageConverters).setControllerAdvice(exceptionTranslator).build();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
    private static InputStream getMessageHistoryResourceAsStream() throws FileNotFoundException {
    ClassLoader classloader = Thread.currentThread().getContextClassLoader();
    InputStream is = classloader.getResourceAsStream("files/messageHistories.json");
    return is;
}

    @Test
public void test() {

    GetRequest getRequest = new GetRequest("mep-report-today", "doc", "1");
    try {
        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);

        System.out.print(response.getSourceAsString());

        SearchRequest searchRequest = new SearchRequest("mep-report-today");
        searchRequest.types("doc");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        searchSourceBuilder.timeout(TimeValue.timeValueMinutes(3));
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();

        System.out.println("********");

        for (SearchHit hit : hits) {

            System.out.println(hit.getId() + " -----" + hit.getSourceAsString());
        }

        System.out.println("********");

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

история сообщений.json

[
  {
    "inventory": "MMS",
    "msg_text": "This is random text",
    "status": "ENROUTE",
    "@timestamp": "2019-09-14T07:59:42.000Z",
    "o_error": "",
    "flight_id": "92348fa1-ca6c-456a-b3b2-85fba2d2deed",
    "recipient": 420736408283,
    "account_id": "a56f7e14-20f9-40e6-90c6-10604140ac5f",
    "sender": 8800111,
    "campaign_id": "6f2abca3-b46d-43f3-91be-3278a8dd7dc0",
    "nof_segments": 1,
    "@version": 1
  },
  {
    "inventory": "SMS",
    "msg_text": "This is random text",
    "status": "ENROUTE",
    "@timestamp": "2019-09-08T08:47:02.000Z",
    "o_error": "",
    "flight_id": "92348fa1-ca6c-456a-b3b2-85fba2d2deed",
    "recipient": 420736408283,
    "account_id": "a56f7e14-20f9-40e6-90c6-10604140ac5f",
    "sender": 8800111,
    "campaign_id": "6f2abca3-b46d-43f3-91be-3278a8dd7dc0",
    "nof_segments": 1,
    "@version": 1
  }]

MessageHistory.java

package com.openmind.primecast.domain.elasticsearch;

import java.time.Instant;
import java.util.UUID;

import com.fasterxml.jackson.annotation.JsonProperty;

public class MessageHistory {

    @JsonProperty("inventory")
    private String inventory;

    @JsonProperty("msg_text")
    private String messageText;

    @JsonProperty("status")
    private String status;

    @JsonProperty("@timestamp")
    private Instant timeStamp;

    @JsonProperty("o_error")
    private String error;

    @JsonProperty("flight_id")
    private UUID flightId;

    @JsonProperty("recipient")
    private String recipient;

    @JsonProperty("account_id")
    private UUID accountId;

    @JsonProperty("sender")
    private String sender;

    @JsonProperty("campaign_id")
    private UUID campaignId;

    @JsonProperty("nof_segments")
    private Integer segmentCount;

    @JsonProperty("@version")
    private Integer version;

    public String getInventory() {
        return inventory;
    }

    public void setInventory(String inventory) {
        this.inventory = inventory;
    }

    public String getMessageText() {
        return messageText;
    }

    public void setMessageText(String messageText) {
        this.messageText = messageText;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Instant getTimeStamp() {
        return timeStamp;
    }

    public void setTimeStamp(Instant timeStamp) {
        this.timeStamp = timeStamp;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public UUID getFlightId() {
        return flightId;
    }

    public void setFlightId(UUID flightId) {
        this.flightId = flightId;
    }

    public String getRecipient() {
        return recipient;
    }

    public void setRecipient(String recipient) {
        this.recipient = recipient;
    }

    public String getSender() {
        return sender;
    }

    public void setSender(String sender) {
        this.sender = sender;
    }

    public UUID getAccountId() {
        return accountId;
    }

    public void setAccountId(UUID accountId) {
        this.accountId = accountId;
    }

    public UUID getCampaignId() {
        return campaignId;
    }

    public void setCampaignId(UUID campaignId) {
        this.campaignId = campaignId;
    }

    public Integer getSegmentCount() {
        return segmentCount;
    }

    public void setSegmentCount(Integer segmentCount) {
        this.segmentCount = segmentCount;
    }

    public Integer getVersion() {
        return version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    @Override
    public String toString() {
        return "MessageHistory [inventory=" + inventory + ", messageText=" + messageText + ", status=" + status
                + ", timeStamp=" + timeStamp + ", error=" + error + ", flightId=" + flightId + ", recipient="
                + recipient + ", accountId=" + accountId + ", sender=" + sender + ", campaignId=" + campaignId
                + ", segmentCount=" + segmentCount + ", version=" + version + "]";
    }

}

поэтому в файле messageHistories.json для каждого объекта есть поле с именем @timestamp, поэтому, когда я сопоставляю этот массив с объектами Java и сохраняю эти объекты как документы под индексом, я теряю форматирование. Другими словами, когда я запускаю интеграционный тест, я получаю этот результат. другими словами, @timestamp хранится в эластичном поиске, например, "@timestamp":1.568447982E9 . то, что я хочу, похоже на это в эластичном поиске "@timestamp": "2019-09-08T08:47:02.000Z"

********
0 -----{"inventory":"MMS","msg_text":"This is random text","status":"ENROUTE","@timestamp":1.568447982E9,"o_error":"","flight_id":"92348fa1-ca6c-456a-b3b2-85fba2d2deed","recipient":"420736408283","account_id":"a56f7e14-20f9-40e6-90c6-10604140ac5f","sender":"8800111","campaign_id":"6f2abca3-b46d-43f3-91be-3278a8dd7dc0","nof_segments":1,"@version":1}
14 -----{"inventory":"MMS","msg_text":"This is random text","status":"ENROUTE","@timestamp":1.56851715E9,"o_error":"","flight_id":"92348fa1-ca6c-456a-b3b2-85fba2d2deed","recipient":"420736408281","account_id":"a56f7e14-20f9-40e6-90c6-10604140ac5f","sender":"8800111","campaign_id":"6f2abca3-b46d-43f3-91be-3278a8dd7dc0","nof_segments":1,"@version":1}
19 -----{"inventory":"MMS","msg_text":"This is random text","status":"ENROUTE","@timestamp":1.56767748E9,"o_error":"","flight_id":"92348fa1-ca6c-456a-b3b2-85fba2d2deed","recipient":"420736408281","account_id":"a56f7e14-20f9-40e6-90c6-10604140ac5f","sender":"8800111","campaign_id":"6f2abca3-b46d-43f3-91be-3278a8dd7dc0","nof_segments":1,"@version":1}
22 -----{"inventory":"MMS","msg_text":"This is random text","status":"ENROUTE","@timestamp":1.568710029E9,"o_error":"","flight_id":"92348fa1-ca6c-456a-b3b2-85fba2d2deed","recipient":"420736408281","account_id":"a56f7e14-20f9-40e6-90c6-10604140ac5f","sender":"8800111","campaign_id":"6f2abca3-b46d-43f3-91be-3278a8dd7dc0","nof_segments":1,"@version":1}
24 -----{"inventory":"MMS","msg_text":"This is random text","status":"ENROUTE","@timestamp":1.568629248E9,"o_error":"","flight_id":"92348fa1-ca6c-456a-b3b2-85fba2d2deed","recipient":"420736408283","account_id":"a56f7e14-20f9-40e6-90c6-10604140ac5f","sender":"8800111","campaign_id":"6f2abca3-b46d-43f3-91be-3278a8dd7dc0","nof_segments":1,"@version":1}
25 -----{"inventory":"SMS","msg_text":"This is random text","status":"ENROUTE","@timestamp":1.569413823E9,"o_error":"","flight_id":"92348fa1-ca6c-456a-b3b2-85fba2d2deed","recipient":"420736408281","account_id":"a56f7e14-20f9-40e6-90c6-10604140ac5f","sender":"8800111","campaign_id":"6f2abca3-b46d-43f3-91be-3278a8dd7dc0","nof_segments":1,"@version":1}
26 -----{"inventory":"MMS","msg_text":"This is random text","status":"ENROUTE","@timestamp":1.568528127E9,"o_error":"","flight_id":"92348fa1-ca6c-456a-b3b2-85fba2d2deed","recipient":"420736408283","account_id":"a56f7e14-20f9-40e6-90c6-10604140ac5f","sender":"8800111","campaign_id":"6f2abca3-b46d-43f3-91be-3278a8dd7dc0","nof_segments":1,"@version":1}
29 -----{"inventory":"MMS","msg_text":"This is random text","status":"ENROUTE","@timestamp":1.569124502E9,"o_error":"","flight_id":"92348fa1-ca6c-456a-b3b2-85fba2d2deed","recipient":"420736408283","account_id":"a56f7e14-20f9-40e6-90c6-10604140ac5f","sender":"8800111","campaign_id":"6f2abca3-b46d-43f3-91be-3278a8dd7dc0","nof_segments":1,"@version":1}
40 -----{"inventory":"SMS","msg_text":"This is random text","status":"ENROUTE","@timestamp":1.568546145E9,"o_error":"","flight_id":"92348fa1-ca6c-456a-b3b2-85fba2d2deed","recipient":"420736408281","account_id":"a56f7e14-20f9-40e6-90c6-10604140ac5f","sender":"8800111","campaign_id":"6f2abca3-b46d-43f3-91be-3278a8dd7dc0","nof_segments":1,"@version":1}
41 -----{"inventory":"SMS","msg_text":"This is random text","status":"ENROUTE","@timestamp":1.568088436E9,"o_error":"","flight_id":"92348fa1-ca6c-456a-b3b2-85fba2d2deed","recipient":"420736408281","account_id":"a56f7e14-20f9-40e6-90c6-10604140ac5f","sender":"8800111","campaign_id":"6f2abca3-b46d-43f3-91be-3278a8dd7dc0","nof_segments":1,"@version":1}
********

Любая идея, как я могу этого достичь?


person KnowledgeSeeker001    schedule 04.09.2019    source источник
comment
Попробуйте заменить @JsonProperty("@timestamp") в MessageHistory.java на @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "UTC") Я использовал это в одном из проектов, но в нашем случае объект имеет тип Date вместо Instant.   -  person ms_27    schedule 05.09.2019


Ответы (1)


После того, как я установил свой ObjectMapper с SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, это хорошо.

ObjectMapper objMapper = new ObjectMapper();
objMapper.registerModule(new JavaTimeModule());
objMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
person KnowledgeSeeker001    schedule 05.09.2019