|
|
@ -0,0 +1,288 @@ |
|
|
|
|
|
package mx.gob.jumapacelaya.api; |
|
|
|
|
|
|
|
|
|
|
|
import com.nimbusds.jose.shaded.gson.*; |
|
|
|
|
|
import mx.gob.jumapacelaya.models.RedmineUser; |
|
|
|
|
|
import mx.gob.jumapacelaya.models.Ticket; |
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.IOException; |
|
|
|
|
|
import java.net.URI; |
|
|
|
|
|
import java.net.http.HttpClient; |
|
|
|
|
|
import java.net.http.HttpRequest; |
|
|
|
|
|
import java.net.http.HttpResponse; |
|
|
|
|
|
import java.time.LocalDate; |
|
|
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
|
|
import java.time.format.DateTimeParseException; |
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
|
import java.util.HashMap; |
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
|
|
@Component |
|
|
|
|
|
public class RedmineClient { |
|
|
|
|
|
|
|
|
|
|
|
private static final int PAGE_SIZE = 25; |
|
|
|
|
|
static String REDMINE_URL; |
|
|
|
|
|
static String API_KEY; |
|
|
|
|
|
public static final Gson GSON = new Gson(); |
|
|
|
|
|
|
|
|
|
|
|
public RedmineClient(@Value("${redmine.url}") String redmineUrl, @Value("${redmine.api_key}") String apiKey) { |
|
|
|
|
|
REDMINE_URL = redmineUrl; |
|
|
|
|
|
API_KEY = apiKey; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//AQUI OBTENGO LOS TICKETS DESDE REDMINE |
|
|
|
|
|
public List<Ticket> getTickets(RedmineUser user, boolean includeClosed) { |
|
|
|
|
|
List<Ticket> tickets = new ArrayList<>(); |
|
|
|
|
|
HttpClient client = HttpClient.newHttpClient(); |
|
|
|
|
|
int offset = 0; |
|
|
|
|
|
|
|
|
|
|
|
// Si includeClose es true, incluira todos los tikets si no, incluira solo los que estan abiertos |
|
|
|
|
|
String statusFilter = includeClosed ? "&status_id=*" : "&status_id=open"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (true) { |
|
|
|
|
|
HttpRequest request = HttpRequest.newBuilder() |
|
|
|
|
|
.uri(URI.create(REDMINE_URL + "/issues.json?key=" + user.getKey() + statusFilter + "&offset=" + offset)) |
|
|
|
|
|
.header("Content-Type", "application/json") |
|
|
|
|
|
.build(); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); |
|
|
|
|
|
if (response.statusCode() == 200) { |
|
|
|
|
|
String responseBody = response.body(); |
|
|
|
|
|
List<Ticket> pageTickets = parseTickets(responseBody); |
|
|
|
|
|
tickets.addAll(pageTickets); |
|
|
|
|
|
if (pageTickets.size() < PAGE_SIZE) { |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
offset += PAGE_SIZE; |
|
|
|
|
|
} else { |
|
|
|
|
|
System.err.println("Error en la respuesta: " + response.statusCode()); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
e.printStackTrace(); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
System.out.println("Total tickets obtenidos: " + tickets.size()); |
|
|
|
|
|
return tickets; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//AQUI OBTENGO LOS TICKETS DESDE REDMINE |
|
|
|
|
|
public List<Ticket> getTicketsAuthor(RedmineUser user) { |
|
|
|
|
|
List<Ticket> tickets = new ArrayList<>(); |
|
|
|
|
|
HttpClient client = HttpClient.newHttpClient(); |
|
|
|
|
|
int offset = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (true) { |
|
|
|
|
|
HttpRequest request = HttpRequest.newBuilder() |
|
|
|
|
|
.uri(URI.create(REDMINE_URL + "/issues.json?key=" + user.getKey() + "&author_id=" + user.getId() + "&offset=" + offset)) |
|
|
|
|
|
.header("Content-Type", "application/json") |
|
|
|
|
|
.build(); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); |
|
|
|
|
|
if (response.statusCode() == 200) { |
|
|
|
|
|
String responseBody = response.body(); |
|
|
|
|
|
List<Ticket> pageTickets = parseTickets(responseBody); |
|
|
|
|
|
tickets.addAll(pageTickets); |
|
|
|
|
|
if (pageTickets.size() < PAGE_SIZE) { |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
offset += PAGE_SIZE; |
|
|
|
|
|
} else { |
|
|
|
|
|
System.err.println("Error en la respuesta: " + response.statusCode()); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
e.printStackTrace(); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
System.out.println("Total tickets obtenidos: " + tickets.size()); |
|
|
|
|
|
return tickets; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Aquí se parsean todos los tickets que existen y se les da un formato con los campos a mostrarse |
|
|
|
|
|
private List<Ticket> parseTickets(String json) { |
|
|
|
|
|
List<Ticket> tickets = new ArrayList<>(); |
|
|
|
|
|
try { |
|
|
|
|
|
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); |
|
|
|
|
|
JsonArray issues = jsonObject.getAsJsonArray("issues"); |
|
|
|
|
|
if (issues != null) { |
|
|
|
|
|
for (JsonElement issueElement : issues) { |
|
|
|
|
|
JsonObject issue = issueElement.getAsJsonObject(); |
|
|
|
|
|
|
|
|
|
|
|
// Verifica y obtiene el ID |
|
|
|
|
|
int id = issue.has("id") && !issue.get("id").isJsonNull() ? issue.get("id").getAsInt() : 0; |
|
|
|
|
|
|
|
|
|
|
|
// Verifica y obtiene el subject |
|
|
|
|
|
String subject = issue.has("subject") && !issue.get("subject").isJsonNull() ? issue.get("subject").getAsString() : ""; |
|
|
|
|
|
|
|
|
|
|
|
// Verifica y obtiene la descripción |
|
|
|
|
|
String description = issue.has("description") && !issue.get("description").isJsonNull() ? issue.get("description").getAsString() : ""; |
|
|
|
|
|
|
|
|
|
|
|
// Verifica y obtiene el status |
|
|
|
|
|
String status = "Unknown"; |
|
|
|
|
|
if (issue.has("status") && !issue.get("status").isJsonNull()) { |
|
|
|
|
|
JsonObject statusObject = issue.getAsJsonObject("status"); |
|
|
|
|
|
if (statusObject.has("name") && !statusObject.get("name").isJsonNull()) { |
|
|
|
|
|
status = statusObject.get("name").getAsString(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Verifica y obtiene la fecha de creación |
|
|
|
|
|
String dateString = issue.has("created_on") && !issue.get("created_on").isJsonNull() ? issue.get("created_on").getAsString() : ""; |
|
|
|
|
|
LocalDate date = null; |
|
|
|
|
|
if (!dateString.isEmpty()) { |
|
|
|
|
|
try { |
|
|
|
|
|
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME; |
|
|
|
|
|
date = LocalDate.parse(dateString, formatter); |
|
|
|
|
|
} catch (DateTimeParseException e) { |
|
|
|
|
|
System.err.println("Error al parsear la fecha: " + dateString); |
|
|
|
|
|
e.printStackTrace(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Verifica y obtiene el ID del tipo de ticket |
|
|
|
|
|
Integer trackerId = null; |
|
|
|
|
|
if (issue.has("tracker") && !issue.get("tracker").isJsonNull()) { |
|
|
|
|
|
JsonObject trackerObject = issue.getAsJsonObject("tracker"); |
|
|
|
|
|
if (trackerObject.has("id") && !trackerObject.get("id").isJsonNull()) { |
|
|
|
|
|
trackerId = trackerObject.get("id").getAsInt(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Agrega el ticket a la lista |
|
|
|
|
|
tickets.add(new Ticket(id, subject, description, status, date != null ? date.toString() : "", trackerId)); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
System.out.println("La respuesta JSON no contiene la clave 'issues'"); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
e.printStackTrace(); |
|
|
|
|
|
System.out.println("Ocurrió un error al parsear los tickets: " + e.getMessage()); |
|
|
|
|
|
} |
|
|
|
|
|
return tickets; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public RedmineUser getMyAccount(String username) { |
|
|
|
|
|
HttpRequest request = HttpRequest.newBuilder() |
|
|
|
|
|
.uri(URI.create(REDMINE_URL + "/my/account.json")) |
|
|
|
|
|
.header("Content-Type", "application/json") |
|
|
|
|
|
.header("X-Redmine-Switch-User", username) |
|
|
|
|
|
.header("X-Redmine-API-Key", API_KEY) |
|
|
|
|
|
.GET() |
|
|
|
|
|
.build(); |
|
|
|
|
|
try { |
|
|
|
|
|
HttpClient client = HttpClient.newHttpClient(); |
|
|
|
|
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); |
|
|
|
|
|
|
|
|
|
|
|
JsonObject jsonObject = JsonParser.parseString(response.body()).getAsJsonObject(); |
|
|
|
|
|
JsonObject userJson = jsonObject.get("user").getAsJsonObject(); |
|
|
|
|
|
|
|
|
|
|
|
RedmineUser user = new RedmineUser(); |
|
|
|
|
|
user.setId(userJson.get("id").getAsInt()); |
|
|
|
|
|
user.setLogin(userJson.get("login").getAsString()); |
|
|
|
|
|
user.setFirstname(userJson.get("firstname").getAsString()); |
|
|
|
|
|
user.setLastname(userJson.get("lastname").getAsString()); |
|
|
|
|
|
user.setMail(userJson.get("mail").getAsString()); |
|
|
|
|
|
user.setKey(userJson.get("api_key").getAsString()); |
|
|
|
|
|
return user; |
|
|
|
|
|
|
|
|
|
|
|
//return response.body(); |
|
|
|
|
|
} catch (IOException | InterruptedException e) { |
|
|
|
|
|
e.printStackTrace(); |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static RedmineUser createRedmineUser(String username, String firstname, String lastname, String mail) { |
|
|
|
|
|
HttpClient client = HttpClient.newHttpClient(); |
|
|
|
|
|
Map<String, Object> user = new HashMap<>(); |
|
|
|
|
|
user.put("login", username); |
|
|
|
|
|
user.put("firstname", firstname); |
|
|
|
|
|
user.put("lastname", lastname); |
|
|
|
|
|
user.put("mail", mail); |
|
|
|
|
|
user.put("auth_source_id", "1"); |
|
|
|
|
|
|
|
|
|
|
|
Map<String, Object> payload = new HashMap<>(); |
|
|
|
|
|
payload.put("user", user); |
|
|
|
|
|
String jsonPayload = new Gson().toJson(payload); |
|
|
|
|
|
HttpRequest request = HttpRequest.newBuilder() |
|
|
|
|
|
.uri(URI.create(REDMINE_URL + "/users.json")) |
|
|
|
|
|
.header("Content-Type", "application/json") |
|
|
|
|
|
.header("X-Redmine-API-Key", API_KEY) |
|
|
|
|
|
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) |
|
|
|
|
|
.build(); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); |
|
|
|
|
|
|
|
|
|
|
|
JsonObject jsonObject = JsonParser.parseString(response.body()).getAsJsonObject(); |
|
|
|
|
|
JsonObject userJson = jsonObject.get("user").getAsJsonObject(); |
|
|
|
|
|
|
|
|
|
|
|
RedmineUser newUser = new RedmineUser(); |
|
|
|
|
|
newUser.setId(userJson.get("id").getAsInt()); |
|
|
|
|
|
newUser.setLogin(userJson.get("login").getAsString()); |
|
|
|
|
|
newUser.setFirstname(userJson.get("firstname").getAsString()); |
|
|
|
|
|
newUser.setLastname(userJson.get("lastname").getAsString()); |
|
|
|
|
|
newUser.setMail(userJson.get("mail").getAsString()); |
|
|
|
|
|
|
|
|
|
|
|
return newUser; |
|
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
e.printStackTrace(); |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//AQUI OBTENGO A LOS USUARIOS |
|
|
|
|
|
//Se devuelven en formato Json |
|
|
|
|
|
public RedmineUser getUserByUsername(String username) { |
|
|
|
|
|
HttpClient client = HttpClient.newHttpClient(); |
|
|
|
|
|
HttpRequest request = HttpRequest.newBuilder() |
|
|
|
|
|
.uri(URI.create(REDMINE_URL + "/users.json?name=" + username )) |
|
|
|
|
|
.header("Content-Type", "application/json") |
|
|
|
|
|
.header("X-Redmine-API-Key", API_KEY) |
|
|
|
|
|
.build(); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); |
|
|
|
|
|
if (response.statusCode() == 200) { |
|
|
|
|
|
String responseBody = response.body(); |
|
|
|
|
|
System.out.println("Datos del usuario " + responseBody); |
|
|
|
|
|
return parseUser(responseBody); |
|
|
|
|
|
} else { |
|
|
|
|
|
System.err.println("Error en la respuesta: " + response.statusCode()); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
e.printStackTrace(); |
|
|
|
|
|
} |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Aqui se parsean a los usuarios y se les da un formato con los campos a mostrarse |
|
|
|
|
|
private RedmineUser parseUser(String json) { |
|
|
|
|
|
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); |
|
|
|
|
|
JsonObject userJson = jsonObject.getAsJsonArray("users").get(0).getAsJsonObject(); |
|
|
|
|
|
|
|
|
|
|
|
RedmineUser user = new RedmineUser(); |
|
|
|
|
|
user.setId(userJson.get("id").getAsInt()); |
|
|
|
|
|
user.setLogin(userJson.get("login").getAsString()); |
|
|
|
|
|
user.setFirstname(userJson.get("firstname").getAsString()); |
|
|
|
|
|
user.setLastname(userJson.get("lastname").getAsString()); |
|
|
|
|
|
user.setMail(userJson.get("mail").getAsString()); |
|
|
|
|
|
//user.setKey(userJson.get("key").getAsString()); |
|
|
|
|
|
return user; |
|
|
|
|
|
} |
|
|
|
|
|
} |