From a679c6d1a2c0ad168e43930a902b7673caab8bf0 Mon Sep 17 00:00:00 2001 From: Rohit Awate Date: Thu, 1 Mar 2018 15:38:44 +0530 Subject: [PATCH] Added BugReporter and added logging when RequestManagers fail --- .gitignore | 1 + .../homewindow/DashboardController.java | 41 +++-- .../com/rohitawate/restaurant/main/Main.java | 3 + .../restaurant/util/BugReporter.java | 168 ++++++++++++++++++ .../rohitawate/restaurant/util/MiscUtils.java | 29 +++ src/main/resources/BugReporter.jar | Bin 0 -> 3462 bytes 6 files changed, 223 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/rohitawate/restaurant/util/BugReporter.java create mode 100644 src/main/resources/BugReporter.jar diff --git a/.gitignore b/.gitignore index 9692bc6..2b7dcd7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ src/main/java/META-INF/ dependency-reduced-pom.xml config/ logs/ +/RESTaurant/BugReporter.jar diff --git a/src/main/java/com/rohitawate/restaurant/homewindow/DashboardController.java b/src/main/java/com/rohitawate/restaurant/homewindow/DashboardController.java index c72bf2f..f88feaa 100644 --- a/src/main/java/com/rohitawate/restaurant/homewindow/DashboardController.java +++ b/src/main/java/com/rohitawate/restaurant/homewindow/DashboardController.java @@ -180,14 +180,15 @@ public class DashboardController implements Initializable { requestManager.setOnFailed(e -> { loadingLayer.setVisible(false); promptLayer.setVisible(false); - Throwable exception = requestManager.getException(); - exception.printStackTrace(); + Throwable throwable = requestManager.getException(); + Exception exception = (Exception) throwable; + Services.loggingService.logWarning("GET request could not be processed.", exception, LocalDateTime.now()); - if (exception.getClass() == UnreliableResponseException.class) { - UnreliableResponseException URE = (UnreliableResponseException) exception; + if (throwable.getClass() == UnreliableResponseException.class) { + UnreliableResponseException URE = (UnreliableResponseException) throwable; errorTitle.setText(URE.getExceptionTitle()); errorDetails.setText(URE.getExceptionDetails()); - } else if (exception.getClass() == ProcessingException.class) { + } else if (throwable.getClass() == ProcessingException.class) { errorTitle.setText("RESTaurant couldn't connect."); errorDetails.setText("Either you are not connected to the Internet or the server is offline."); } @@ -233,23 +234,24 @@ public class DashboardController implements Initializable { requestManager.setOnFailed(e -> { loadingLayer.setVisible(false); promptLayer.setVisible(false); - Throwable exception = requestManager.getException(); - exception.printStackTrace(); + Throwable throwable = requestManager.getException(); + Exception exception = (Exception) throwable; + Services.loggingService.logWarning(httpMethodBox.getValue() + " request could not be processed.", exception, LocalDateTime.now()); - if (exception.getClass() == UnreliableResponseException.class) { - UnreliableResponseException URE = (UnreliableResponseException) exception; + if (throwable.getClass() == UnreliableResponseException.class) { + UnreliableResponseException URE = (UnreliableResponseException) throwable; errorTitle.setText(URE.getExceptionTitle()); errorDetails.setText(URE.getExceptionDetails()); - } else if (exception.getClass() == ProcessingException.class) { - if (exception.getCause().getClass() == UnknownHostException.class || - exception.getCause().getClass() == ConnectException.class) { + } else if (throwable.getClass() == ProcessingException.class) { + if (throwable.getCause().getClass() == UnknownHostException.class || + throwable.getCause().getClass() == ConnectException.class) { errorTitle.setText("RESTaurant couldn't connect."); errorDetails.setText("Either you are not connected to the Internet or the server is offline."); - } else if (exception.getCause().getClass() == IllegalArgumentException.class) { + } else if (throwable.getCause().getClass() == IllegalArgumentException.class) { errorTitle.setText("Did you forget something?"); errorDetails.setText("Please specify at least one body part for your " + httpMethodBox.getValue() + " request."); } - } else if (exception.getClass() == FileNotFoundException.class) + } else if (throwable.getClass() == FileNotFoundException.class) snackBar.show("File could not be found.", 5000); errorLayer.setVisible(true); requestManager.reset(); @@ -288,14 +290,15 @@ public class DashboardController implements Initializable { requestManager.setOnFailed(e -> { loadingLayer.setVisible(false); promptLayer.setVisible(false); - Throwable exception = requestManager.getException(); - exception.printStackTrace(); + Throwable throwable = requestManager.getException(); + Exception exception = (Exception) throwable; + Services.loggingService.logWarning("DELETE request could not be processed.", exception, LocalDateTime.now()); - if (exception.getClass() == UnreliableResponseException.class) { - UnreliableResponseException URE = (UnreliableResponseException) exception; + if (throwable.getClass() == UnreliableResponseException.class) { + UnreliableResponseException URE = (UnreliableResponseException) throwable; errorTitle.setText(URE.getExceptionTitle()); errorDetails.setText(URE.getExceptionDetails()); - } else if (exception.getClass() == ProcessingException.class) { + } else if (throwable.getClass() == ProcessingException.class) { errorTitle.setText("No Internet Connection"); errorDetails.setText("Could not connect to the server. Please check your connection."); } diff --git a/src/main/java/com/rohitawate/restaurant/main/Main.java b/src/main/java/com/rohitawate/restaurant/main/Main.java index 3b0e675..05af750 100644 --- a/src/main/java/com/rohitawate/restaurant/main/Main.java +++ b/src/main/java/com/rohitawate/restaurant/main/Main.java @@ -15,6 +15,7 @@ */ package com.rohitawate.restaurant.main; +import com.rohitawate.restaurant.util.MiscUtils; import com.rohitawate.restaurant.util.Services; import com.rohitawate.restaurant.util.settings.SettingsLoader; import com.rohitawate.restaurant.util.themes.ThemeManager; @@ -44,6 +45,8 @@ public class Main extends Application { dashboardStage.setScene(new Scene(homeWindow)); dashboardStage.setTitle("RESTaurant"); dashboardStage.show(); + + MiscUtils.createBugReporter(); } public static void main(String args[]) { diff --git a/src/main/java/com/rohitawate/restaurant/util/BugReporter.java b/src/main/java/com/rohitawate/restaurant/util/BugReporter.java new file mode 100644 index 0000000..7aa11d8 --- /dev/null +++ b/src/main/java/com/rohitawate/restaurant/util/BugReporter.java @@ -0,0 +1,168 @@ +/* + * Copyright 2018 Rohit Awate. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.rohitawate.restaurant.util; + +import java.io.*; +import java.nio.charset.Charset; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Scanner; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class BugReporter { + public static void main(String args[]) { + Scanner scanner = new Scanner(System.in); + System.out.println("RESTaurant Bug Reporting Service"); + System.out.println(); + System.out.println("Please describe the issue with as much detail and clarity as possible: "); + String userMessage = scanner.nextLine(); + StringBuilder builder = new StringBuilder(); + builder.append("\nThank you for your input! The issue was recorded.\n\n"); + builder.append("With your permission, this service can collect some anonymous, non-personal information about your system.\n"); + builder.append("This information will help us to better reproduce the issue and fix it quickly.\n"); + builder.append("This includes:\n"); + builder.append(" - Operating system details.\n"); + builder.append(" - Details about your Java Runtime Environment.\n\n"); + builder.append("Allow? (Y/N)\n>> "); + System.out.print(builder.toString()); + String allowSystemData = scanner.nextLine(); + + allowSystemData = allowSystemData.toLowerCase(); + + StringBuilder report = new StringBuilder(); + report.append("Log date: "); + report.append(LocalDateTime.now()); + report.append("\n\n"); + if (allowSystemData.equals("y") || allowSystemData.equals("yes")) { + report.append(generateSystemDetails()); + System.out.println("\nThat's great! We will include your system details in with the bug report."); + } else { + System.out.println("\nAlrighty! We will only include RESTaurant's log files in the report."); + } + + scanner.close(); + report.append("User Message:\n"); + report.append(userMessage); + generateReport(report.toString()); + generateZipFile(); + + System.out.println("\nYour issue was successfully reported and will be fixed soon."); + System.out.println("Thank you! :)"); + } + + private static String generateSystemDetails() { + StringBuilder builder = new StringBuilder(); + String OS = System.getProperty("os.name"); + if (OS.equals("Linux")) { + builder.append(getLinuxDetails()); + } + builder.append("OS: "); + builder.append(OS); + builder.append(" "); + builder.append(System.getProperty("os.arch")); + builder.append(" "); + builder.append(System.getProperty("os.version")); + builder.append("\n"); + builder.append("Java VM: "); + builder.append(System.getProperty("java.vm.name")); + builder.append(" "); + builder.append(System.getProperty("java.version")); + builder.append("\nJava VM Vendor: "); + builder.append(System.getProperty("java.vendor")); + builder.append("\n\n"); + + return builder.toString(); + } + + private static void generateReport(String reportContents) { + String reportFileName = "Report - " + LocalDate.now() + ".txt"; + try { + BufferedWriter writer = new BufferedWriter(new FileWriter("logs/" + reportFileName)); + writer.write(reportContents); + writer.close(); + } catch (IOException IOE) { + IOE.printStackTrace(); + } + } + + private static void generateZipFile() { + try { + Scanner scanner; + FileInputStream fileInputStream; + ZipOutputStream zipStream = new ZipOutputStream(new FileOutputStream("Logs.zip"), Charset.forName("UTF-8")); + File sourceDir = new File("logs/"); + String[] logFiles = sourceDir.list(); + + for (String logFile : logFiles) { + zipStream.putNextEntry(new ZipEntry(logFile)); + + fileInputStream = new FileInputStream("logs/" + logFile); + scanner = new Scanner(fileInputStream); + + while (scanner.hasNext()) { + zipStream.flush(); + zipStream.write(scanner.nextLine().getBytes()); + zipStream.write('\n'); + } + + zipStream.closeEntry(); + scanner.close(); + fileInputStream.close(); + } + + zipStream.close(); + } catch (IOException IOE) { + IOE.printStackTrace(); + } + } + + private static String getLinuxDetails() { + String line = ""; + + try { + File etcDir = new File("/etc/"); + String releaseFile = ""; + for (String file : etcDir.list()) { + if (file.endsWith("-release")) { + releaseFile = file; + break; + } + } + BufferedReader reader = new BufferedReader(new FileReader("/etc/" + releaseFile)); + + while ((line = reader.readLine()) != null) { + if (line.startsWith("PRETTY_NAME")) + break; + } + reader.close(); + if (!line.equals("")) { + line = "Distribution: " + line.substring(13, line.length() - 1) + "\n"; + } + } catch (IOException IOE) { + line = ""; + Scanner scanner = new Scanner(System.in); + System.out.println("We couldn't fetch information about your Linux distribution. Please fill in the following details:"); + System.out.println("Distribution name: "); + line += "Distribution: " + scanner.nextLine() + "\n"; + System.out.println("Version: "); + line += "Version: " + scanner.nextLine() + "\n"; + scanner.close(); + } + return line; + } +} diff --git a/src/main/java/com/rohitawate/restaurant/util/MiscUtils.java b/src/main/java/com/rohitawate/restaurant/util/MiscUtils.java index e7f978b..7d96b83 100644 --- a/src/main/java/com/rohitawate/restaurant/util/MiscUtils.java +++ b/src/main/java/com/rohitawate/restaurant/util/MiscUtils.java @@ -16,6 +16,14 @@ package com.rohitawate.restaurant.util; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; + public class MiscUtils { /** * Removes leading and trailing quotation marks from strings. @@ -26,4 +34,25 @@ public class MiscUtils { public static String trimString(String input) { return input.replaceAll("\"", ""); } + + /** + * Copies the BugReporter from within the JAR to the installation directory. + */ + public static void createBugReporter() { + new Thread(() -> { + File bugReporterFile = new File("RESTaurant/BugReporter.jar"); + if (!bugReporterFile.exists()) { + InputStream inputStream = MiscUtils.class.getResourceAsStream("/BugReporter.jar"); + Path bugReporter = Paths.get("RESTaurant/BugReporter.jar"); + try { + Files.copy(inputStream, bugReporter); + } catch (IOException e) { + e.printStackTrace(); + } + Services.loggingService.logInfo("BugReporter was copied to installation folder.", LocalDateTime.now()); + } else { + Services.loggingService.logInfo("BugReporter was found.", LocalDateTime.now()); + } + }).start(); + } } diff --git a/src/main/resources/BugReporter.jar b/src/main/resources/BugReporter.jar new file mode 100644 index 0000000000000000000000000000000000000000..be670cf9d857b3cdcd97bada1d24c29eac044dcf GIT binary patch literal 3462 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 F{srrBGco`G literal 0 HcmV?d00001