@Override
  public Token getToken() {
    if (null == token || token.isExpired()) {
      try {
        ObjectNode objectNode = factory.objectNode();
        objectNode.put("grant_type", "client_credentials");
        objectNode.put("client_id", tokenKey1);
        objectNode.put("client_secret", tokenKey2);
        List<NameValuePair> headers = new ArrayList<>();
        headers.add(new BasicNameValuePair("Content-Type", "application/json"));

        HttpPost httpPost = new HttpPost();
        httpPost.setURI(tokenURL.toURI());

        for (NameValuePair nameValuePair : headers) {
          httpPost.addHeader(nameValuePair.getName(), nameValuePair.getValue());
        }
        httpPost.setEntity(new StringEntity(objectNode.toString(), "UTF-8"));

        HttpResponse tokenResponse = client.execute(httpPost);
        HttpEntity entity = tokenResponse.getEntity();

        String results = EntityUtils.toString(entity, "UTF-8");

        if (tokenResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {

          ObjectMapper mapper = new ObjectMapper();

          JsonFactory factory = mapper.getJsonFactory();
          JsonParser jp = factory.createJsonParser(results);
          JsonNode json = mapper.readTree(jp);

          String accessToken = json.get("access_token").asText();
          Long expiredAt = System.currentTimeMillis() + json.get("expires_in").asLong() * 1000;

          db.updateToken(accessToken, expiredAt);

          token = new Token(accessToken, expiredAt);
        }
      } catch (Exception e) {
        throw new RuntimeException(
            "Some errors occurred while fetching a token by username and password .");
      }
    }

    return token;
  }