JavaRush /Java Blog /Random-TK /Howa biletleriniň bahasyna gözegçilik ulgamyny döretmek: ...

Howa biletleriniň bahasyna gözegçilik ulgamyny döretmek: ädimme-ädim gollanma [1-nji bölüm]

Toparda çap edildi

Mazmuny:

Howa biletleriniň bahalaryna gözegçilik etmek üçin ulgam döretmek: ädimme-ädim gollanma [1-nji bölüm] - 1Hemmelere salam, JavaRush jemgyýeti! Bu gün howa biletleriniň bahalaryna ädimme-ädim gözegçilik etmek üçin “Bahar boot” programmasyny nädip ýazmalydygy barada gürleşeris. Makala barada pikiri bolan adamlar üçin niýetlenendir:
  • REST we REST ahyrky nokatlaryň nähili gurulýandygyny;
  • baglanyşyk bazalary;
  • maveniň işi (esasanam garaşlylyk näme);
  • JSON obýekti;
  • hasaba alyş ýörelgeleri.
Garaşylýan özüni alyp baryş:
  1. Belli bir senä uçuş saýlap, onuň bahasyny yzarlap bilersiňiz. Ulanyjy e-poçta salgysy bilen kesgitlenýär. Bahanyň üýtgemegine abuna ýazylan badyna, ulanyjy e-poçta arkaly habarnamany alýar.
  2. Her 30 minutdan (bu aralyk application.properties arkaly düzülýär) uçuşyň iň pes bahasy ähli abunalar üçin gaýtadan hasaplanýar. Gymmatlyklaryň biri peselse, ulanyjy e-poçta arkaly habarnamany alar.
  3. Könelen uçuş senesi bolan ähli abunalyklar öçüriler.
  4. REST API arkaly edip bilersiňiz:
    • abuna ýazmak;
    • redaktirlemek;
    • ähli abunalary e-poçta bilen almak;
    • abunalygy poz.

Maksada ýetmek üçin hereket meýilnamasy

Uçuşlar baradaky maglumatlaryň bir ýerden alynmalydygyna başlamaly. Adatça, web sahypalary açyk REST API üpjün edýär, onuň üsti bilen maglumat alyp bolýar.

API (programma programmirleme interfeýsi), bir programma bilen täsirleşip boljak interfeýsdir. Mundan REST API nämedigine köpri gurup bileris.

REST API, web programmasy bilen habarlaşmak üçin ulanyp boljak REST haýyşlarynyň interfeýsi.

Munuň üçin Skyscanner , has dogrusy, API ulanarys ( Rakuten API web sahypasynda ). Ondan soň esasy esas hökmünde dogry çarçuwany saýlamaly. Iň meşhur we isleg Bahar ekosistemasy we olaryň döredilmeginiň täji - Bahar aýakgaby. Resmi web sahypasyna girip bilersiňiz ýa-da Habre baradaky makalany okap bilersiňiz . Ulanyjy abunalaryny saklamak üçin, içindäki H2 maglumat bazasyny ulanarys . JSON-dan sapaklara we yza çenli okamak üçin Jekson Taslamasyny ulanarys ( ine, çeşmämizdäki baglanyşyk ). Ulanyjylara habar ibermek üçin bahar-boot-starter-mail ulanarys . Programmanyň belli bir ýygylykda iň pes bahany täzeden hasaplamagy üçin Bahar meýilnamasyny ulanarys . REST API döretmek üçin bahar-boot-starter-web ulanarys . Karz alnan kody (getterler, sazlaýjylar, deňhukuklary we hashkody, obýektler üçin toString () ýazmazlyk üçin Lombok Taslamasyny ulanarys . REST API-ni duýmak we görmek üçin Swagger 2 ulanarys we real wagt yzarlamak üçin derrew Swagger UI (ulanyjy interfeýsi) ulanarys. Ine, häzir nähili görünýär: Howa biletleriniň bahasyna gözegçilik ulgamyny döretmek: ädimme-ädim gollanma [1-nji bölüm] - 2abunalary döretmek, redaktirlemek, almak we pozmak bilen baglanyşykly 4 sany dynç alyş soragy bar.

Skyscanner API-ni öwrenmek

Geliň, rakuten api baglanyşygyna eýereliň . Ilki bilen hasaba alynmaly. Howa biletleriniň bahasyna gözegçilik ulgamyny döretmek: ädimme-ädim gollanma [1-nji bölüm] - 3Bularyň hemmesi öz sahypasyny ulanmak we onda ýerleşdirilen köpçülige açyk API-lerden haýyş etmek üçin özboluşly açar almak üçin zerurdyr. Bu API-leriň biri bize zerur bolan Skyscanner Uçuş Gözlegidir . Indi onuň nähili işleýändigini anyklalyň. Geliň, sanaw sanaw ýerleri talaplaryny tapalyň. Surat, maglumatlary doldurmaly we Test Endpoint-i başlamalydygyňyzy görkezýär , netijede sag tarapda JSON obýekti görnüşinde jogap alýarys Howa biletleriniň bahalaryna gözegçilik etmek üçin ulgam döretmek: ädimme-ädim gollanma [1-nji bölüm] - 4we haýyş şeýle dörediler:

https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com/apiservices/autosuggest/v1.0/{country}/{currency}/{locale}/?query={query}
we ähli parametrler şu formula bilen çalşyrylar, biz alarys:

https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com/apiservices/autosuggest/v1.0/UK/GBP/en-GB/?query=Stockholm
we bu haýyşlara iki sözbaşy berler:

.header("x-rapidapi-host", "skyscanner-skyscanner-flight-search-v1.p.rapidapi.com")
.header("x-rapidapi-key", "sing-up-for-key"),
hasaba alnandan soň berilýär sign-up-for-key. Bahanyň aşaklamagyny yzarlamak üçin, “Göz aýlamak” ahyrky nokady gerek bolar. Özüňiz tapyň :)

“Bahar boot” esasynda programma çarçuwasyny döretmek

“Spring Boot” bilen çalt we aňsatlyk bilen taslama döretmek üçin “Bahar Initializr” -ini ulanyp bilersiňiz . Aşakdaky saýlawlary saýlaň:
  1. Maven taslamasy
  2. Java
  3. 2.1.10
  4. topar - haýsy zerur diýip pikir etseňiz, mysal üçin ru.javarush
  5. artifakt - edil birmeňzeş, mysal üçin uçuşlara gözegçilik
  6. garaşlylyk gözleginde aşakdakylary gözleýäris:
    • Bahar webi
    • Java poçta iberiji
    • Bahar maglumatlary Jpa
    • H2 maglumat bazasy
Soň bolsa "Generate" düwmesine basyň . Ine: taýýar taslama arhiw hökmünde göçüriler. Bir zat netije bermese, islenýän taslamany ýatda saklan linkimi ulanyp bilersiňiz . Elbetde, muny özüňiz edip, nähili işleýändigine düşünmek has gowudyr. Programma üç gatlakdan ybarat bolar:
  • KONTROLLER - programma giriň. REST API şu ýerde düşündiriler
  • HYZMAT biznes logika gatlagydyr. Programmanyň ähli logikasy şu ýerde beýan ediler.
  • REPOSITORY - maglumat bazasy bilen işlemek üçin gatlak.
Şeýle hem, “Skyscanner Uçuş Gözleg API” -ni müşderi bilen baglanyşykly sapaklar aýratyn bukja bolar.

Taslamadaky “Skyscanner Uçuş Gözleg API” -ine haýyşlar üçin bir müşderi ýazýarys

Skyscanner, API-ni nädip ulanmalydygy barada hoşniýetli makala berdi (işjeň haýyş bilen sessiýa döretmeris). "Müşderi ýazmak" nämäni aňladýar? Belli bir parametrleri bolan belli bir URL-e haýyş döretmeli we bize gaýtarylan maglumatlar üçin DTO (maglumat geçiriş obýekti) taýýarlamaly. Sahypada haýyşlaryň dört topary bar:
  1. Göni uçuş gözlegi - häzirki wagtda zerur däl hasaplamarys.
  2. Placeserler - ýazalyň.
  3. Uçuş bahalaryna göz aýlaň - ähli maglumatlary alyp boljak bir haýyşy ulanarys.
  4. Lokalizasiýa - haýsy maglumatlary goldaýandygyny bilmek üçin goşalyň.

Lokalizasiýa haýyşy üçin müşderi hyzmatyny dörediň:

Meýilnama buglanan şalgam ýaly ýönekeý: haýyş dörediň, parametrlere serediň, jogaba serediň. Iki sorag bar: Markerleri we walýutalary sanaň. Walýutalardan başlalyň. Surat munuň goşmaça meýdanlar bolmazdan haýyşdygyny görkezýär: goldanýan walýutalar barada maglumat almak zerur: Howa biletleriniň bahasyna gözegçilik ulgamyny döretmek: ädimme-ädim gollanma [1-nji bölüm] - 6Jogap, şol bir obýektleriň ýygyndysyny öz içine alýan JSON obýekt görnüşinde.
{
"Code":"LYD"
"Symbol":"د.ل.‏"
"ThousandsSeparator":","
"DecimalSeparator":"."
"SymbolOnLeft":true
"SpaceBetweenAmountAndSymbol":false
"RoundingCoefficient":0
"DecimalDigits":3
}
Geliň, bu obýekt üçin “CurrencyDto” döredeliň:
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

/**
* Data transfer object for Currency.
*/
@Data
public class CurrencyDto {

   @JsonProperty("Code")
   private String code;

   @JsonProperty("Symbol")
   private String symbol;

   @JsonProperty("ThousandsSeparator")
   private String thousandsSeparator;

   @JsonProperty("DecimalSeparator")
   private String decimalSeparator;

   @JsonProperty("SymbolOnLeft")
   private boolean symbolOnLeft;

   @JsonProperty("SpaceBetweenAmountAndSymbol")
   private boolean spaceBetweenAmountAndSymbol;

   @JsonProperty("RoundingCoefficient")
   private int roundingCoefficient;

   @JsonProperty("DecimalDigits")
   private int decimalDigits;
}
Nirede:
  • @Data Lombok taslamasynyň düşündirişidir we ähli girişleri, sazlaýjylary döredýär ,String () -e deňleşdirýär, deňdir () we hashCode () usullaryny döredýär. Kodyň okalmagyny gowulandyrýan we POJO obýektlerini ýazmagyň wagtyny çaltlaşdyrýan zat ;
  • @JsonProperty ("Kod") bu üýtgeýjä haýsy meýdanyň beriljekdigini aýdýan Jekson Taslamasynyň düşündirişidir. .Agny, JSON-da Koda deň bolan meýdan kod üýtgeýjisine berler .
Skyscanner-iň resmi makalasy UniRest kitaphanasyny REST haýyşlary üçin ulanmagy teklip edýär . Şonuň üçin haýyşlary REST arkaly amala aşyrjak başga bir hyzmat ýazarys. Bu UniRestService bolar . Munuň üçin maven üçin täze garaşlylyk goşuň:
<dependency>
  <groupId>com.mashape.unirest</groupId>
  <artifactId>unirest-java</artifactId>
  <version>1.4.9</version>
</dependency>
Indiki, REST haýyşlaryny ýerine ýetirjek hyzmat ýazarys. Elbetde, her bir müşderi / hyzmat üçin interfeýs dörederis we ony durmuşa geçireris:
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;

/**
* Service, which is manipulating with Rest calls.
*/
public interface UniRestService {

   /**
   * Create GET request based on provided {@param path} with needed headers.
   *
   * @param path provided path with all the needed data
   * @return {@link HttpResponse<jsonnode>} response object.
   */
   HttpResponse<jsonnode> get(String path);

}
Ony durmuşa geçirmek:
import com.github.romankh3.flightsmonitoring.exception.FlightClientException;
import com.github.romankh3.flightsmonitoring.client.service.UniRestService;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
* {@inheritDoc}
*/
@Slf4j
@Service
public class UniRestServiceImpl implements UniRestService {

   public static final String HOST = "https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com";

   public static final String PLACES_FORMAT = "/apiservices/autosuggest/v1.0/%s/%s/%s/?query=%s";
   public static final String CURRENCIES_FORMAT = "/apiservices/reference/v1.0/currencies";
   public static final String COUNTRIES_FORMAT = "/apiservices/reference/v1.0/countries/%s";

   public static final String PLACES_KEY = "Places";
   public static final String CURRENCIES_KEY = "Currencies";
   public static final String COUNTRIES_KEY = "Countries";

   @Value("${x.rapid.api.key}")
   private String xRapidApiKey;

   /**
    * {@inheritDoc}
    */
   @Override
   public HttpResponse<jsonnode> get(String path) {
       HttpResponse<jsonnode> response = null;
       try {
           response = Unirest.get(HOST + path)
                   .header("x-rapidapi-host", "skyscanner-skyscanner-flight-search-v1.p.rapidapi.com")
                   .header("x-rapidapi-key", xRapidApiKey)
                   .asJson();
       } catch (UnirestException e) {
           throw new FlightClientException(String.format("Request failed, path=%s", HOST + path), e);
       }

       log.info("Response from Get request, on path={}, statusCode={}, response={}", path, response.getStatus(), response.getBody().toString());
       return response;
   }
}
Onuň düýp manysy, gyzyklandyrýan ähli isleglerimiz GET haýyşlary üçin döredildi we bu hyzmat taýýar haýyşy kabul edýär we aşakdaky ýaly zerur sözbaşylary goşýar:
.header("x-rapidapi-host", "skyscanner-skyscanner-flight-search-v1.p.rapidapi.com")
.header("x-rapidapi-key", xRapidApiKey)
Sypatlardan maglumat almak üçin aşakda görkezilişi ýaly @Value düşündirişini ulanyň:
@Value("${x.rapid.api.key}")
private String xRapidApiKey;
Application.properties-de bu üýtgeýjä sanjym edilmeli x.rapid.api.key atly bir emläk boljakdygyny aýdýar. Gaty kodlanan bahalardan dynýarys we bu üýtgeýjiniň kesgitlemesini programma kodundan alýarys. Mundan başga-da, bu programmany GitHub-da çap edenimde, bu emlägiň bahasyny goşmaýaryn. Bu howpsuzlyk sebäpli edilýär. REST haýyşlary bilen işleýän bir hyzmat ýazdyk, indi Lokalizasiýa hyzmatynyň wagty geldi. OOP esasynda bir programma gurýarys, şonuň üçin “LocalizationClient” interfeýsini döredýäris we “LocalisationClientImpl” :
import com.github.romankh3.flightsmonitoring.client.dto.CountryDto;
import com.github.romankh3.flightsmonitoring.client.dto.CurrencyDto;
import java.io.IOException;
import java.util.List;

/**
* Client for SkyScanner localisation.
*/
public interface LocalisationClient {

   /**
    * Retrieve the market countries that SkyScanner flight search API support. Most suppliers (airlines,
    * travel agents and car hire dealers) set their fares based on the market (or country of purchase).
    * It is therefore necessary to specify the market country in every query.
    *
    * @param locale locale of the response.
    *
    * @return the collection of the {@link CountryDto} objects.
    *
    * @throws IOException
    */
   List<CountryDto> retrieveCountries(String locale);

   /**
    * Retrieve the currencies that we ScyScanner flight search API.
    *
    * @return the collection of the {@link CurrencyDto} objects.
    *
    * @throws IOException
    */
   List<CurrencyDto> retrieveCurrencies();

}
we “LocalizationClientImpl” -iň durmuşa geçirilmegi
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.COUNTRIES_FORMAT;
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.COUNTRIES_KEY;
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.CURRENCIES_FORMAT;
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.CURRENCIES_KEY;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.romankh3.flightsmonitoring.client.dto.CountryDto;
import com.github.romankh3.flightsmonitoring.client.dto.CurrencyDto;
import com.github.romankh3.flightsmonitoring.client.service.LocalisationClient;
import com.github.romankh3.flightsmonitoring.client.service.UniRestService;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.exceptions.UnirestException;
import java.io.IOException;
import java.util.List;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
* {@inheritDoc}
*/
@Component
public class LocalisationClientImpl implements LocalisationClient {

   @Autowired
   private UniRestService uniRestService;

   @Autowired
   private ObjectMapper objectMapper;

   /**
    * {@inheritDoc}
    */
   @Override
   public List<CountryDto> retrieveCountries(String locale) throws IOException {
       HttpResponse<JsonNode> response = uniRestService.get(String.format(COUNTRIES_FORMAT, locale));

       if (response.getStatus() != HttpStatus.SC_OK) {
           return null;
       }

       String jsonList = response.getBody().getObject().get(COUNTRIES_KEY).toString();

       return objectMapper.readValue(jsonList, new TypeReference<List<CountryDto>>() {
       });
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public List<CurrencyDto> retrieveCurrencies() throws IOException, UnirestException {

       HttpResponse<JsonNode> response = uniRestService.get(CURRENCIES_FORMAT);
       if (response.getStatus() != HttpStatus.SC_OK) {
           return null;
       }

       String jsonList = response.getBody().getObject().get(CURRENCIES_KEY).toString();

       return objectMapper.readValue(jsonList, new TypeReference<List<CurrencyDto>>() {
       });
   }
}
Nirede
  • @Autowired, bu klasa bir obýekt sanjym etmeli we ony döretmezden ulanmaly, ýagny täze Obýekt işlemezden ulanmaly diýýär;
  • @Komponent, bu obýektiň Programma kontekstine goşulmalydygyny, soň bolsa @Autowired düşündirişini ulanyp sanjym ediljekdigini aýdýar;
  • ObjectMapper objectMapper, bularyň hemmesini Java obýektlerine terjime edýän Jekson Taslamasynyň obýektidir.
  • WalýutaDTO we CountryDto:
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

/**
* Data transfer object for Currency.
*/
@Data
public class CurrencyDto {

   @JsonProperty("Code")
   private String code;

   @JsonProperty("Symbol")
   private String symbol;

   @JsonProperty("ThousandsSeparator")
   private String thousandsSeparator;

   @JsonProperty("DecimalSeparator")
   private String decimalSeparator;

   @JsonProperty("SymbolOnLeft")
   private boolean symbolOnLeft;

   @JsonProperty("SpaceBetweenAmountAndSymbol")
   private boolean spaceBetweenAmountAndSymbol;

   @JsonProperty("RoundingCoefficient")
   private int roundingCoefficient;

   @JsonProperty("DecimalDigits")
   private int decimalDigits;
}
	и
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

/**
* Data transfer object for Country.
*/
@Data
public class CountryDto {

   @JsonProperty("Code")
   private String code;

   @JsonProperty("Name")
   private String name;
}
Taslamanyň islendik bölegine “ObjectMapper” sanjym etmek üçin, konfigurasiýa synpy arkaly “ApplicationContext” -e döretmegi we goşmagy goşdum.
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* {@link Configuration} class.
*/
@Configuration
public class Config {

   @Bean
   public ObjectMapper objectMapper() {
       ObjectMapper objectMapper = new ObjectMapper();
       objectMapper.registerModule(new JavaTimeModule());
       return objectMapper;
   }
}
@ Konfigurasiýa düşündirişi Bahara bu synpda käbir konfigurasiýalaryň boljakdygyny aýdýar. Diňe munuň üçin ObjectMapper goşdum. Edil şonuň ýaly, PlacesClient we PlacesClientImpl goşýarys:
import com.github.romankh3.flightsmonitoring.client.dto.PlaceDto;
import com.github.romankh3.flightsmonitoring.client.dto.PlacesDto;
import com.mashape.unirest.http.exceptions.UnirestException;
import java.io.IOException;
import java.util.List;

/**
* SkyScanner client.
*/
public interface PlacesClient {

   /**
    * Get a list of places that match a query string based on arguments.
    *
    * @param query the code of the city.
    * @param country the code of the country.
    * @param currency the code of the currency.
    * @param locale the code of the locale.
    * @return the collection of the {@link PlaceDto} objects.
    */
   List<PlacesDto> retrieveListPlaces(String query, String country, String currency, String locale)
           throws IOException, UnirestException;
}
we
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.PLACES_FORMAT;
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.PLACES_KEY;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.romankh3.flightsmonitoring.client.dto.PlacesDto;
import com.github.romankh3.flightsmonitoring.client.service.PlacesClient;
import com.github.romankh3.flightsmonitoring.client.service.UniRestService;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.exceptions.UnirestException;
import java.io.IOException;
import java.util.List;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
* {@inheritDoc}
*/
@Service
public class PlacesClientImpl implements PlacesClient {

   @Autowired
   private UniRestService uniRestService;

   @Autowired
   private ObjectMapper objectMapper;


   /**
    * {@inheritDoc}
    */
   @Override
   public List<PlacesDto> retrieveListPlaces(String query, String country, String currency, String locale)
           throws IOException, UnirestException {
       HttpResponse<JsonNode> response = uniRestService
               .get(String.format(PLACES_FORMAT, country, currency, locale, query));

       if (response.getStatus() != HttpStatus.SC_OK) {
           return null;
       }

       String jsonList = response.getBody().getObject().get(PLACES_KEY).toString();

       return objectMapper.readValue(jsonList, new TypeReference<List<PlacesDto>>() {
       });
   }
}
“PlacesDto” görnüşi bar:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.romankh3.flightsmonitoring.client.service.PlacesClient;
import lombok.Data;

/**
* Using for {@link PlacesClient}.
*/
@Data
public class PlacesDto {

   @JsonProperty("PlaceId")
   private String placeId;

   @JsonProperty("PlaceName")
   private String placeName;

   @JsonProperty("CountryId")
   private String countryId;

   @JsonProperty("RegionId")
   private String regionId;

   @JsonProperty("CityId")
   private String cityId;

   @JsonProperty("CountryName")
   private String countryName;
}
Netijede, zerur maglumatlara esaslanyp, uçuş üçin iň pes bahany we ähli zerur maglumatlary yzyna gaýtaryp berjek müşderi hyzmaty: FlightPriceClient we FlightPriceClientImpl. Diňe bir haýyşy amala aşyrarys, browseQuotes. Uçuş bahasy:
import com.github.romankh3.flightsmonitoring.client.dto.FlightPricesDto;

/**
* Browse flight prices.
*/
public interface FlightPricesClient {

   /**
    * Browse quotes for current flight based on provided arguments. One-way ticket.
    *
    * @param country the country from
    * @param currency the currency to get price
    * @param locale locale for the response
    * @param originPlace origin place
    * @param destinationPlace destination place
    * @param outboundPartialDate outbound date
    * @return {@link FlightPricesDto} object.
    */
   FlightPricesDto browseQuotes(String country, String currency, String locale, String originPlace,
           String destinationPlace, String outboundPartialDate);

   /**
    * Browse quotes for current flight based on provided arguments. Round trip ticket.
    *
    * @param country the country from
    * @param currency the currency to get price
    * @param locale locale for the response
    * @param originPlace origin place
    * @param destinationPlace destination place
    * @param outboundPartialDate outbound date
    * @param inboundPartialDate inbound date
    * @return {@link FlightPricesDto} object.
    */
   FlightPricesDto browseQuotes(String country, String currency, String locale, String originPlace,
           String destinationPlace, String outboundPartialDate, String inboundPartialDate);
}
FlightPriceClientImpl
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.CURRENCIES_KEY;
import static com.github.romankh3.flightsmonitoring.client.service.impl.UniRestServiceImpl.PLACES_KEY;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.romankh3.flightsmonitoring.client.dto.CarrierDto;
import com.github.romankh3.flightsmonitoring.client.dto.CurrencyDto;
import com.github.romankh3.flightsmonitoring.client.dto.FlightPricesDto;
import com.github.romankh3.flightsmonitoring.client.dto.PlaceDto;
import com.github.romankh3.flightsmonitoring.client.dto.QuoteDto;
import com.github.romankh3.flightsmonitoring.client.dto.ValidationErrorDto;
import com.github.romankh3.flightsmonitoring.client.service.FlightPricesClient;
import com.github.romankh3.flightsmonitoring.client.service.UniRestService;
import com.github.romankh3.flightsmonitoring.exception.FlightClientException;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import java.io.IOException;
import java.util.List;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
* {@inheritDoc}
*/
@Service
public class FlightPricesClientImpl implements FlightPricesClient {

   public static final String BROWSE_QUOTES_FORMAT = "/apiservices/browsequotes/v1.0/%s/%s/%s/%s/%s/%s";
   public static final String OPTIONAL_BROWSE_QUOTES_FORMAT = BROWSE_QUOTES_FORMAT + "?inboundpartialdate=%s";

   public static final String QUOTES_KEY = "Quotes";
   public static final String ROUTES_KEY = "Routes";
   public static final String DATES_KEY = "Dates";
   public static final String CARRIERS_KEY = "Carriers";
   public static final String VALIDATIONS_KEY = "ValidationErrors";

   @Autowired
   private UniRestService uniRestService;

   @Autowired
   private ObjectMapper objectMapper;

   /**
    * {@inheritDoc}
    */
   @Override
   public FlightPricesDto browseQuotes(String country, String currency, String locale, String originPlace,
           String destinationPlace, String outboundPartialDate) {

       HttpResponse<JsonNode> response = uniRestService.get(String
               .format(BROWSE_QUOTES_FORMAT, country, currency, locale, originPlace, destinationPlace,
                       outboundPartialDate));
       return mapToObject(response);
   }

   public FlightPricesDto browseQuotes(String country, String currency, String locale, String originPlace,
           String destinationPlace, String outboundPartialDate, String inboundPartialDate) {
       HttpResponse<JsonNode> response = uniRestService.get(String
               .format(OPTIONAL_BROWSE_QUOTES_FORMAT, country, currency, locale, originPlace, destinationPlace,
                       outboundPartialDate, inboundPartialDate));
       return mapToObject(response);
   }

   private FlightPricesDto mapToObject(HttpResponse<JsonNode> response) {
       if (response.getStatus() == HttpStatus.SC_OK) {
           FlightPricesDto flightPricesDto = new FlightPricesDto();
           flightPricesDto.setQuotas(readValue(response.getBody().getObject().get(QUOTES_KEY).toString(),
                   new TypeReference<List<QuoteDto>>() {
                   }));
           flightPricesDto.setCarriers(readValue(response.getBody().getObject().get(CARRIERS_KEY).toString(),
                   new TypeReference<List<CarrierDto>>() {
                   }));
           flightPricesDto.setCurrencies(readValue(response.getBody().getObject().get(CURRENCIES_KEY).toString(),
                   new TypeReference<List<CurrencyDto>>() {
                   }));
           flightPricesDto.setPlaces(readValue(response.getBody().getObject().get(PLACES_KEY).toString(),
                   new TypeReference<List<PlaceDto>>() {
                   }));
           return flightPricesDto;
       }
       throw new FlightClientException(String.format("There are validation errors. statusCode = %s", response.getStatus()),
               readValue(response.getBody().getObject().get(VALIDATIONS_KEY).toString(),
                       new TypeReference<List<ValidationErrorDto>>() {
                       }));
   }

   private <T> List<T> readValue(String resultAsString, TypeReference<List<T>> valueTypeRef) {
       List<T> list;
       try {
           list = objectMapper.readValue(resultAsString, valueTypeRef);
       } catch (IOException e) {
           throw new FlightClientException("Object Mapping failure.", e);
       }
       return list;
   }
}
“FlightClientException” şu ýerde:
import com.github.romankh3.flightsmonitoring.client.dto.ValidationErrorDto;
import java.util.List;

/**
* A {@link RuntimeException} that is thrown in case of an flight monitoring failures.
*/
public final class FlightClientException extends RuntimeException {

   public FlightClientException(String message) {
       super(message);
   }

   public FlightClientException(String message, Throwable throwable) {
       super(message, throwable);
   }

   public FlightClientException(String message, List<ValidationErrorDto> errors) {
       super(message);
       this.validationErrorDtos = errors;
   }

   private List<ValidationErrorDto> validationErrorDtos;
}
Netijede, PlacesCl-iň maglumatlaryna görä
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION