├── src ├── main │ ├── resources │ │ ├── code.json │ │ ├── log4j2.xml │ │ └── config.properties │ ├── webapp │ │ ├── favicon.ico │ │ ├── index.html │ │ └── WEB-INF │ │ │ └── web.xml │ └── java │ │ └── gov │ │ └── faa │ │ └── ait │ │ └── apra │ │ ├── util │ │ ├── ChartCycleJsonUnmarshaller.java │ │ ├── JsonUtil.java │ │ ├── ChartInfoTable.java │ │ ├── URLCache.java │ │ ├── TACSpecialCase.java │ │ ├── GenericsUtil.java │ │ ├── ChartInfoTableKey.java │ │ ├── TableChartClient.java │ │ ├── SupplementMetadataClient.java │ │ └── CycleDateUtil.java │ │ ├── cycle │ │ ├── ChartCycleData.java │ │ ├── ChartCycleElementsJson.java │ │ ├── DenodoClient.java │ │ ├── HelicopterChartCycleClient.java │ │ └── WallPlanningChartCycleClient.java │ │ ├── json │ │ ├── TPPChartMetadata.java │ │ ├── SupplementChartMetadata.java │ │ ├── USState.java │ │ ├── USStateReference.java │ │ └── SupplementMetadata.java │ │ ├── bootstrap │ │ ├── ErrorCodes.java │ │ ├── TPPVolume.java │ │ └── USStateReferenceData.java │ │ ├── path │ │ ├── ProductPath.java │ │ └── PathElement.java │ │ └── api │ │ ├── DownloadServiceApp.java │ │ ├── ProductApiListener.java │ │ ├── management │ │ └── ManagementControl.java │ │ ├── DigitalEnrouteSupplementCharts.java │ │ └── DailyDigitalObstacleFile.java └── test │ └── java │ └── gov │ └── faa │ └── ait │ └── apra │ └── test │ ├── TPPVolumeTest.java │ ├── KeyTest.java │ ├── DDOFTest.java │ ├── IfrPlanningChartsTest.java │ ├── SectionalChartsTest.java │ ├── StateReferenceTest.java │ ├── ManagementTest.java │ ├── DECTest.java │ ├── VerifyValues.java │ ├── SectionalChartTableTest.java │ ├── DERSTest.java │ ├── NASRTest.java │ ├── ChartCycleTest.java │ ├── IFREnrouteFunctionalTest.java │ ├── SectionalChartClientTest.java │ ├── CycleDateTest.java │ ├── CIFPTest.java │ ├── WallPlanningChartsTest.java │ ├── IFREnrouteChartsTest.java │ ├── VFRChartsTest.java │ ├── CityNameConversionTest.java │ ├── HelicopterChartsTest.java │ ├── VFRFunctionalTest.java │ ├── GOMTest.java │ ├── CIFP2Test.java │ ├── HelicopterFunctionalTest.java │ └── SupplementFunctionalTest.java ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md └── pom.xml /src/main/resources/code.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Federal-Aviation-Administration/APRA/HEAD/src/main/resources/code.json -------------------------------------------------------------------------------- /src/main/webapp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Federal-Aviation-Administration/APRA/HEAD/src/main/webapp/favicon.ico -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Public domain 2 | 3 | This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the CC0 1.0 Universal public domain dedication. 4 | 5 | All contributions to this project will be released under the CC0 dedication. By submitting a pull request or modifying any of this project's content you are agreeing to comply with this waiver of copyright interest. 6 | -------------------------------------------------------------------------------- /src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Aeronautic Product Release API - APRA 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/util/ChartCycleJsonUnmarshaller.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.util; 15 | 16 | import gov.faa.ait.apra.cycle.ChartCycleData; 17 | 18 | public class ChartCycleJsonUnmarshaller extends JsonUtil { 19 | public ChartCycleJsonUnmarshaller() { 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/TPPVolumeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import gov.faa.ait.apra.bootstrap.TPPVolume; 17 | import static org.junit.Assert.fail; 18 | 19 | import org.junit.Test; 20 | 21 | public class TPPVolumeTest { 22 | 23 | @Test 24 | public void getNortheastTest () { 25 | if (! TPPVolume.isValidVolumeName("NE-1")) 26 | fail(); 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/KeyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.*; 17 | 18 | import org.junit.Test; 19 | 20 | import gov.faa.ait.apra.util.ChartInfoTableKey; 21 | 22 | public class KeyTest { 23 | 24 | @Test 25 | public void test() { 26 | ChartInfoTableKey k1 = new ChartInfoTableKey("ALBUQUERQUE", "CURRENT", "SECTIONAL"); 27 | ChartInfoTableKey k2 = new ChartInfoTableKey("ALBUQUERQUE", "NEXT", "SECTIONAL"); 28 | 29 | assertEquals(k1,k1); 30 | assertEquals(k2,k2); 31 | assertEquals(k1.hashCode(), k1.hashCode()); 32 | assertEquals(k2.hashCode(), k2.hashCode()); 33 | assertNotEquals(k1,k2); 34 | assertNotEquals(k1.hashCode(), k2.hashCode()); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | As a work of the United States government, this project is in the public domain within the United States. 2 | 3 | Additionally, we waive copyright and related rights in the work worldwide through the CC0 1.0 Universal public domain dedication. 4 | 5 | CC0 1.0 Universal summary 6 | 7 | This is a human-readable summary of the Legal Code found here: https://creativecommons.org/publicdomain/zero/1.0/legalcode 8 | 9 | No copyright 10 | 11 | The person who associated a work with this deed has dedicated the work to the public domain by waiving all rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. 12 | 13 | You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. 14 | 15 | Other information 16 | 17 | In no way are the patent or trademark rights of any person affected by CC0, nor are the rights that other persons may have in the work or in how the work is used, such as publicity or privacy rights. 18 | 19 | Unless expressly stated otherwise, the person who associated a work with this deed makes no warranties about the work, and disclaims liability for all uses of the work, to the fullest extent permitted by applicable law. When using or citing the work, you should not imply endorsement by the author or the affirmer. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Aeronautic Product Release API (APRA) 2 | 3 | APRA provides the private sector greater access to core FAA data to spur more innovation in the aviation industry, 4 | and ultimately advance the FAA's mission of safety in flight. Based on stakeholder recommendations, this 5 | initiative's first effort strived to provide both more data and better data for Aeronautical products and 6 | information. Solution Delivery developed and deployed web services for several aeronautical products including both 7 | information about those products and the ability to automatically download those products which satisfied one of 8 | the recommendations. 9 | 10 | ## About APRA 11 | 12 | APRA provides a mechanism for a client program to scan the FAA public web site for a specific type of aeronautic 13 | product for download. The aeronautic products available include charts in various formats. Such charts are often 14 | released to the public on either a 28 day or 56 day airspace cycle. Upon release of charts, the URL(s) for 15 | the chart retrieval necessarily change. APRA constructs the standard URL where the chart may be downloaded 16 | to enable a software application to pull the charts without the need for a human interface or web based GUI. 17 | 18 | ## Documentation 19 | 20 | Documentation for the API may be found on swaggerhub 21 | https://app.swaggerhub.com/apis/FAA/APRA 22 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/DDOFTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.fail; 17 | 18 | import javax.ws.rs.core.Response; 19 | 20 | import org.junit.Test; 21 | 22 | import gov.faa.ait.apra.api.DailyDigitalObstacleFile; 23 | 24 | public class DDOFTest { 25 | 26 | @Test 27 | public void releaseTest () { 28 | DailyDigitalObstacleFile ddof = new DailyDigitalObstacleFile(); 29 | Response response = ddof.getDDOFRelease(); 30 | if (response.getStatus() != 200) 31 | fail(); 32 | } 33 | 34 | @Test 35 | public void editionTest () { 36 | DailyDigitalObstacleFile ddof = new DailyDigitalObstacleFile(); 37 | Response response = ddof.getDDOFEdition(); 38 | if (response.getStatus() != 200) 39 | fail(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %X{ID} %c{1} - %msg%n 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %X{ID} %c{1} - %msg%n 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/cycle/ChartCycleData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.cycle; 15 | 16 | public class ChartCycleData { 17 | private String name; 18 | private ChartCycleElementsJson [] elements; 19 | 20 | public ChartCycleData () { 21 | name = ""; 22 | elements = new ChartCycleElementsJson [1]; 23 | } 24 | 25 | public ChartCycleData (String name, ChartCycleElementsJson [] elements) { 26 | this.name = new String (name); 27 | this.elements = elements.clone(); 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name; 36 | } 37 | 38 | public ChartCycleElementsJson [] getElements() { 39 | return elements.clone(); 40 | } 41 | 42 | public void setElements(ChartCycleElementsJson [] elements) { 43 | this.elements = elements.clone(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/json/TPPChartMetadata.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.json; 15 | 16 | /** 17 | * This class holds the top level TPP chart metadata object as returned by denodo. This is just a POJO data class 18 | * for the denodo response of the serialized and virtualized XML metadata file for TPP 19 | * 20 | */ 21 | public class TPPChartMetadata { 22 | private String name; 23 | private TPPMetadata[] elements; 24 | 25 | public TPPChartMetadata () { 26 | name = ""; 27 | elements = new TPPMetadata [1]; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name; 36 | } 37 | 38 | public TPPMetadata [] getElements() { 39 | return elements.clone(); 40 | } 41 | 42 | public void setElements(TPPMetadata [] elements) { 43 | this.elements = elements.clone(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/json/SupplementChartMetadata.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.json; 15 | 16 | /** 17 | * This class holds the top level Supplement chart metadata object as returned by denodo. 18 | * This is just a POJO data class for the denodo response of the serialized and virtualized 19 | * XML metadata file for Supplement 20 | * 21 | * @author FAA 22 | * 23 | */ 24 | public class SupplementChartMetadata { 25 | private String name; 26 | private SupplementMetadata[] elements; 27 | 28 | public SupplementChartMetadata () { 29 | name = ""; 30 | elements = new SupplementMetadata [1]; 31 | } 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | public void setName(String name) { 38 | this.name = name; 39 | } 40 | 41 | public SupplementMetadata [] getElements() { 42 | return elements.clone(); 43 | } 44 | 45 | public void setElements(SupplementMetadata [] elements) { 46 | this.elements = elements.clone(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/bootstrap/ErrorCodes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.bootstrap; 15 | 16 | /** 17 | * This class is used to manage the error codes and error responses that can be returned from the application 18 | * @author FAA 19 | * 20 | */ 21 | public class ErrorCodes { 22 | 23 | // Hide the default public constructor. This is a utility class that needs no constructor 24 | private ErrorCodes () { } 25 | 26 | public static final String RESPONSE_200="OK"; 27 | public static final String ERROR_400="Illegal arguments provided to service. One or more of the service parameter values is invalid"; 28 | public static final String ERROR_404="Requested edition has not been released for download or could not be found on the FAA aeronav web site."; 29 | public static final String ERROR_500="Internal service error occurred which prevented a valid response from being returned."; 30 | public static final String DEPRECATED="This product has been deprecated and is no longer published by the FAA."; 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/IfrPlanningChartsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.*; 17 | 18 | import java.util.Calendar; 19 | 20 | import org.junit.Test; 21 | 22 | import gov.faa.ait.apra.api.UsIfrVfrPlanning; 23 | import gov.faa.ait.apra.jaxb.ProductSet; 24 | import gov.faa.ait.apra.util.TableChartClient; 25 | 26 | public class IfrPlanningChartsTest { 27 | 28 | @Test 29 | public void test() { 30 | Calendar cal = Calendar.getInstance(); 31 | //cal.set(2016, 05, 15); // careful, 0-based month 32 | TableChartClient client = new TableChartClient(cal.getTime()); 33 | UsIfrVfrPlanning api = new UsIfrVfrPlanning(client); 34 | ProductSet result = (ProductSet) api.getIfrPlanningChart("current", "pdf").getEntity(); 35 | assertTrue(!result.getEdition().isEmpty()); 36 | String url = result.getEdition().get(0).getProduct().getUrl(); 37 | assertTrue("URL was null",url!=null); 38 | assertTrue("URL did not match pattern",url.matches("http://aeronav.faa.gov/enroute/IFR_Planning/[0-9]{2}-[0-9]{2}-[0-9]{4}/US_IFR_Planning_pdf.zip")); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/SectionalChartsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.*; 17 | 18 | import java.util.Calendar; 19 | 20 | import org.junit.Test; 21 | 22 | import gov.faa.ait.apra.api.SectionalCharts; 23 | import gov.faa.ait.apra.bootstrap.ErrorCodes; 24 | import gov.faa.ait.apra.jaxb.ProductSet; 25 | import gov.faa.ait.apra.jaxb.ProductSet.Edition; 26 | 27 | public class SectionalChartsTest { 28 | 29 | @Test 30 | public void test() { 31 | SectionalCharts api = new SectionalCharts(); 32 | ProductSet result = (ProductSet) api.getSectionalChart("Albuquerque", "current", "pdf").getEntity(); 33 | assertTrue(!result.getEdition().isEmpty()); 34 | Edition ed = result.getEdition().get(0); 35 | assertEquals(100,ed.getEditionNumber()); 36 | } 37 | 38 | @Test 39 | public void testInvalidCity() { 40 | SectionalCharts api = new SectionalCharts(); 41 | ProductSet result = (ProductSet) api.getSectionalChart("Albuquer", "current", "pdf").getEntity(); 42 | assertEquals(Integer.valueOf(404),result.getStatus().getCode()); 43 | assertEquals(ErrorCodes.ERROR_404, result.getStatus().getMessage()); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/StateReferenceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.fail; 17 | 18 | import java.util.Locale; 19 | 20 | import org.apache.commons.lang3.text.WordUtils; 21 | import org.junit.Test; 22 | 23 | 24 | import gov.faa.ait.apra.bootstrap.USStateReferenceData; 25 | 26 | public class StateReferenceTest { 27 | 28 | @Test 29 | public void getNebraskaByAbbr () { 30 | String nebraska = USStateReferenceData.getStateName("NE"); 31 | if (! "NEBRASKA".equals(nebraska)) 32 | fail(); 33 | } 34 | 35 | @Test 36 | public void getNebraskaByName () { 37 | String nebraska = USStateReferenceData.getAbbreviation("NEBRASKA"); 38 | if (! "NE".equals(nebraska)) 39 | fail(); 40 | } 41 | 42 | @Test 43 | public void getNewYorkByAbbr () { 44 | String newYork = USStateReferenceData.getStateName("NY"); 45 | if (! "NEW YORK".equals(newYork)) 46 | fail(); 47 | } 48 | 49 | @Test 50 | public void getNewYorkCapitalized () { 51 | String newYork = USStateReferenceData.getStateName("NY"); 52 | char[] separators = {'-', '_', ' '}; 53 | String capitalized = WordUtils.capitalize(newYork.toLowerCase(Locale.ENGLISH), separators); 54 | if (! "New York".equals(capitalized)) 55 | fail(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/ManagementTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import org.junit.Test; 19 | 20 | import gov.faa.ait.apra.api.management.ManagementControl; 21 | 22 | public class ManagementTest { 23 | 24 | @Test 25 | public void getStatus () { 26 | ManagementControl check = new ManagementControl(); 27 | ManagementControl.start(); 28 | String state = check.getStatus(); 29 | assertEquals(state, "ServerOK"); 30 | } 31 | 32 | @Test 33 | public void getStart () { 34 | ManagementControl check = new ManagementControl(); 35 | ManagementControl.start(); 36 | String state = check.getStatus(); 37 | assertEquals(state, "ServerOK"); 38 | } 39 | 40 | @Test 41 | public void getStop () { 42 | ManagementControl check = new ManagementControl(); 43 | ManagementControl.stop(); 44 | String state = check.getStatus(); 45 | assertEquals(state, "ServerDown"); 46 | } 47 | 48 | @Test 49 | public void refresh () { 50 | ManagementControl check = new ManagementControl(); 51 | assertEquals(check.refresh(), "Cycle Reload Complete"); 52 | } 53 | 54 | @Test 55 | public void reloadConfig () { 56 | ManagementControl check = new ManagementControl(); 57 | assertEquals(check.reloadConfig(), "Config Reload Complete"); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/json/USState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.json; 15 | 16 | /** 17 | * This class represents a US state. It contains the US state full name and its 2-letter abbreviation. This is the 18 | * class that Jackson serializes from a JSON object set into a POJO 19 | * 20 | */ 21 | public class USState { 22 | private String abbreviation; 23 | private String name; 24 | 25 | /** 26 | * Default null constructor returns District of Columbia, DC 27 | */ 28 | public USState () { 29 | abbreviation = "DC"; 30 | name = "District of Columbia"; 31 | } 32 | 33 | /** 34 | * Get the state 2-letter abbreviation 35 | * @return the 2-letter abbreviation as a string 36 | */ 37 | public String getAbbreviation() { 38 | return abbreviation; 39 | } 40 | 41 | /** 42 | * Set the state 2-letter abbreviation 43 | * @param abbreviation 44 | */ 45 | public void setAbbreviation(String abbreviation) { 46 | this.abbreviation = abbreviation; 47 | } 48 | 49 | /** 50 | * Get the state proper name 51 | * @return proper name of the state or territory 52 | */ 53 | public String getName() { 54 | return name; 55 | } 56 | 57 | /** 58 | * Set the state proper name 59 | * @param name state or territory name 60 | */ 61 | public void setName(String name) { 62 | this.name = name; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/json/USStateReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.json; 15 | 16 | /** 17 | * A US state reference set of information that includes state name and abbreviation. 18 | * Used by Jackson to marshal and unmarshal the JSON objects from the denodo reference data set 19 | * 20 | */ 21 | public class USStateReference { 22 | private String name; 23 | private USState [] elements; 24 | 25 | /** 26 | * Default constructor initializes members 27 | */ 28 | 29 | public USStateReference () { 30 | name = ""; 31 | elements = null; 32 | } 33 | 34 | /** 35 | * Get the name of the reference set 36 | * @return name of the reference set 37 | */ 38 | public String getName() { 39 | return name; 40 | } 41 | 42 | /** 43 | * Set the name of the reference set 44 | * @param name the name of the reference data set 45 | */ 46 | public void setName(String name) { 47 | this.name = name; 48 | } 49 | 50 | /** 51 | * Get the elements of the reference set as an array. The elements contain the listing of US states and their 2-letter abbreviations 52 | * @return all of the elements from the reference data set 53 | */ 54 | public USState [] getElements() { 55 | return elements.clone(); 56 | } 57 | 58 | /** 59 | * Set the elements of the data set. A listing of all US state names and abbreviations 60 | * @param elements the list of states and abbreviations 61 | */ 62 | public void setElements(USState [] elements) { 63 | this.elements = elements.clone(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/util/JsonUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.util; 15 | 16 | import java.io.IOException; 17 | import java.text.SimpleDateFormat; 18 | import java.util.List; 19 | 20 | import com.fasterxml.jackson.core.JsonParseException; 21 | import com.fasterxml.jackson.databind.DeserializationFeature; 22 | import com.fasterxml.jackson.databind.JsonMappingException; 23 | import com.fasterxml.jackson.databind.ObjectMapper; 24 | import com.google.common.base.Charsets; 25 | /** 26 | * Unmarshalling utility class for json data. Target type must extend this. 27 | * This construct was due to Java Generics and type erasure. 28 | * 29 | * @author FAA 30 | * 31 | * @param 32 | */ 33 | public abstract class JsonUtil { 34 | 35 | /** 36 | * 37 | * @param unbound 38 | * @return 39 | * @throws IOException 40 | * @throws JsonParseException 41 | * @throws JsonMappingException 42 | */ 43 | @SuppressWarnings("unchecked") 44 | public T unmarshalJson(String unbound) 45 | throws IOException, JsonParseException, JsonMappingException { 46 | ObjectMapper mapper = new ObjectMapper(); 47 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 48 | mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); 49 | mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); 50 | Class targetClass = (Class) GenericsUtil.getTypeArguments(JsonUtil.class, this.getClass()).get(0); 51 | return (T) mapper.readValue(unbound.getBytes(Charsets.UTF_16), targetClass); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/util/ChartInfoTable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.util; 15 | 16 | import java.util.concurrent.ConcurrentHashMap; 17 | 18 | import gov.faa.ait.apra.cycle.ChartCycleData; 19 | import gov.faa.ait.apra.cycle.ChartCycleElementsJson; 20 | 21 | /** 22 | * This class stores Chart Info from ChartCycleJson in a map format 23 | * @author FAA 24 | * 25 | */ 26 | public class ChartInfoTable extends ConcurrentHashMap { 27 | 28 | /** 29 | * 30 | */ 31 | private static final long serialVersionUID = -4599811904037606947L; 32 | 33 | /** 34 | * Default constructor, empty map with default capacity 35 | */ 36 | public ChartInfoTable() { 37 | super(); 38 | } 39 | 40 | /** 41 | * Constructor for default capacity, with data to load 42 | * @param chartCycle the chart cycle information in json model class 43 | */ 44 | public ChartInfoTable(ChartCycleData chartCycle) { 45 | super(); 46 | load(chartCycle); 47 | } 48 | 49 | /** 50 | * Method to reload chart cycle data 51 | * @param chartCycle Chart cycle data in json model eclass 52 | */ 53 | public void load(ChartCycleData chartCycle) { 54 | for(ChartCycleElementsJson element: chartCycle.getElements()) { 55 | //System.out.println(element.getChart_city_name()+"; "+element.getChart_cycle_number()+"; "+element.getChart_cycle_period_code()+"; "+element.getChart_cycle_type_code()); 56 | ChartInfoTableKey key = new ChartInfoTableKey( 57 | element.getChart_city_name().toUpperCase(), 58 | element.getChart_cycle_period_code().toUpperCase(), 59 | element.getChart_cycle_type_code().toUpperCase()); 60 | this.put(key, element); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/DECTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | import static org.junit.Assert.fail; 19 | 20 | import javax.ws.rs.core.Response; 21 | 22 | import org.junit.Test; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | import gov.faa.ait.apra.api.DigitalEnrouteCharts; 27 | import gov.faa.ait.apra.cycle.ChartCycleClient; 28 | import gov.faa.ait.apra.jaxb.ProductSet; 29 | 30 | public class DECTest { 31 | private DigitalEnrouteCharts dec; 32 | private static final Logger logger = LoggerFactory.getLogger(DECTest.class); 33 | 34 | public DECTest () { 35 | ChartCycleClient client = new ChartCycleClient(); 36 | client.forceUpdate(); 37 | } 38 | 39 | @Test 40 | public void testCurrentRelease() { 41 | dec = new DigitalEnrouteCharts(); 42 | Response ps = dec.getDECRelease("current"); 43 | int code = ps.getStatus(); 44 | assertEquals(code, 200); 45 | ProductSet psEntity = (ProductSet) ps.getEntity(); 46 | assertTrue(VerifyValues.verifyURL(psEntity.getEdition().get(0).getProduct().getUrl())); 47 | } 48 | 49 | @Test 50 | public void testNextRelease() { 51 | dec = new DigitalEnrouteCharts(); 52 | Response ps = dec.getDECRelease("next"); 53 | int code = ps.getStatus(); 54 | 55 | // Have to allow for either a positive response or a not found due to the AJV release cycle. A "next" edition may 56 | // only be published 20 days in advance. Therefore, there is a time period when we may ask for "next", but it really hasn't 57 | // been put on the web site yet 58 | if (! (code == 200 || code == 404) ) { 59 | fail(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/resources/config.properties: -------------------------------------------------------------------------------- 1 | gov.faa.ait.aeronav.host=http://www.aeronav.faa.gov 2 | gov.faa.ait.denodo.host=https://soadev.sm.faa.gov 3 | gov.faa.ait.nfdc.host=https://nfdc.faa.gov 4 | gov.faa.ait.aeronav.upload.folder=upload_313-d 5 | gov.faa.ait.aeronav.sectional.folder=/content/aeronav/sectional_files 6 | gov.faa.ait.aeronav.vfr.upload.folder=content/aeronav/grand_canyon_files 7 | gov.faa.ait.aeronav.wallplan.upload.folder=content/aeronav/grand_canyon_files 8 | gov.faa.ait.aeronav.enroute.upload.folder=enroute 9 | gov.faa.ait.aeronav.helicopter.upload.folder=content/aeronav/heli_files 10 | gov.faa.ait.denodo.cycle.resource=/denodo/apra/server/ifpa/edai/views/chart_cycle 11 | gov.faa.ait.denodo.vfr.cycle.resource=/denodo/apra/server/ifpa/edai/vfr_chart_cycle 12 | gov.faa.ait.cycle.ageLimit=1 13 | gov.faa.ait.sup.chart.path=/afd 14 | gov.faa.ait.nfdc.nasr.path=/webContent/28DaySub 15 | gov.faa.ait.nasr.date.format=yyyy-MM-dd 16 | gov.faa.ait.nasr.file.prefix=28DaySubscription_Effective_ 17 | gov.faa.ait.sup.us.path=/upload_313-d/supplements 18 | gov.faa.ait.sup.check.flag=false 19 | gov.faa.ait.nasr.check.flag=false 20 | 21 | 22 | # DMZ proxy information. Required for APRA to reach back to the Intranet for denodo support services 23 | # If proxy not required, leave blank 24 | gov.faa.dmz.proxy.host=http://dmzproxy.esc.gov 25 | gov.faa.dmz.proxy.port=8080 26 | 27 | # IFR en route properties 28 | gov.faa.ait.enroute.count.us.area.pdf=1 29 | gov.faa.ait.enroute.count.us.area.tiff=2 30 | gov.faa.ait.enroute.count.us.low.tiff=36 31 | gov.faa.ait.enroute.count.us.low.pdf=36 32 | gov.faa.ait.enroute.count.us.high.tiff=12 33 | gov.faa.ait.enroute.count.us.high.pdf=12 34 | gov.faa.ait.enroute.count.alaska.low.tiff=4 35 | gov.faa.ait.enroute.count.alaska.low.pdf=4 36 | gov.faa.ait.enroute.count.alaska.high.tiff=2 37 | gov.faa.ait.enroute.count.alaska.high.pdf=2 38 | gov.faa.ait.enroute.count.pacific.low.tiff=0 39 | gov.faa.ait.enroute.count.pacific.low.pdf=0 40 | gov.faa.ait.enroute.count.pacific.high.tiff=2 41 | gov.faa.ait.enroute.count.pacific.high.pdf=2 42 | gov.faa.ait.enroute.count.caribbean.area.pdf=4 43 | gov.faa.ait.enroute.count.caribbean.area.tiff=0 44 | gov.faa.ait.enroute.count.caribbean.low.pdf=6 45 | gov.faa.ait.enroute.count.caribbean.high.pdf=2 46 | gov.faa.ait.enroute.count.caribbean.low.tiff=0 47 | gov.faa.ait.enroute.count.caribbean.high.tiff=0 48 | 49 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/path/ProductPath.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.path; 15 | 16 | import java.util.ArrayList; 17 | 18 | /** 19 | * Represents a path to a file which contains multiple path elements such as directories or a file. 20 | * @author FAA 21 | * 22 | */ 23 | public class ProductPath { 24 | 25 | private ArrayList path; 26 | private boolean complete = false; 27 | 28 | /** 29 | * Null constructor to create the default path 30 | */ 31 | public ProductPath () { 32 | this.path = new ArrayList <> (); 33 | this.complete = false; 34 | } 35 | 36 | /** 37 | * Add a new path element to this path 38 | * @param pe the path element to add to this path 39 | */ 40 | public void addPathElement (PathElement pe) { 41 | if (!complete) { 42 | if (pe.isFile()) { 43 | this.complete = true; 44 | } 45 | path.add(pe); 46 | } 47 | 48 | return; 49 | } 50 | 51 | /** 52 | * Add the final or last path element. Once the last path element is set, the path is immutable 53 | * @param pe 54 | */ 55 | public void addLastElement (PathElement pe) { 56 | 57 | if (! complete) { 58 | this.addPathElement(pe); 59 | this.complete = true; 60 | } 61 | 62 | return; 63 | } 64 | 65 | /** 66 | * Get an external representation of the path using the standard / path separator character. Once the final element is reached, the path is 67 | * set and returned. 68 | * @return 69 | */ 70 | public String getPathAsString () { 71 | StringBuilder pathString = new StringBuilder ("/"); 72 | for (PathElement pe : path) { 73 | pathString = pathString.append(pe.getPathElement()); 74 | if (pe.isDirectory()) { 75 | pathString = pathString.append ("/"); 76 | } 77 | } 78 | return pathString.toString(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/api/DownloadServiceApp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.api; 15 | 16 | import java.util.HashSet; 17 | import java.util.Set; 18 | 19 | import javax.ws.rs.core.Application; 20 | 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | 24 | import io.swagger.jaxrs.config.BeanConfig; 25 | 26 | /** 27 | * This is the base application for CIFP and represents the JAX-RS application for scanning of REST services through the classes that are specified. 28 | * @author FAA 29 | * 30 | */ 31 | public class DownloadServiceApp extends Application { 32 | private static final Logger logger = LoggerFactory.getLogger(DownloadServiceApp.class); 33 | 34 | public DownloadServiceApp () { 35 | BeanConfig beanConfig = new BeanConfig(); 36 | beanConfig.setTitle("FAA Aeronautic Product Release API"); 37 | beanConfig.setVersion("1.1.0"); 38 | beanConfig.setSchemes(new String [] {"https"}); 39 | beanConfig.setHost("soa.smext.faa.gov"); 40 | beanConfig.setBasePath("/apra"); 41 | beanConfig.setResourcePackage("io.swagger.resources"); 42 | beanConfig.setLicense("US Public Domain"); 43 | beanConfig.setLicenseUrl("http://www.usa.gov/publicdomain/label/1.0/"); 44 | beanConfig.setScan(true); 45 | } 46 | 47 | @Override 48 | public Set> getClasses() { 49 | if (logger.isDebugEnabled()) 50 | logger.debug("Resource classes being retrieved from AirportStatus jersey application."); 51 | Set> s = new HashSet <>(); 52 | s.add(gov.faa.ait.apra.api.CIFP.class); 53 | s.add(gov.faa.ait.apra.api.ProductApiListener.class); 54 | s.add(io.swagger.jaxrs.listing.ApiListingResource.class); 55 | s.add(io.swagger.jaxrs.listing.SwaggerSerializers.class); 56 | 57 | //Manually adding MOXyJSONFeature 58 | s.add(org.glassfish.jersey.moxy.json.MoxyJsonFeature.class); 59 | 60 | return s; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/VerifyValues.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import java.io.IOException; 17 | import java.net.HttpURLConnection; 18 | import java.net.InetSocketAddress; 19 | import java.net.Proxy; 20 | import java.net.URL; 21 | 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | 25 | import gov.faa.ait.apra.bootstrap.Config; 26 | 27 | public class VerifyValues { 28 | private final static Logger logger = LoggerFactory.getLogger(VerifyValues.class); 29 | private final static String EMPTY_STRING=""; 30 | 31 | private VerifyValues () { } 32 | 33 | public static boolean verifyURL (String urlString) { 34 | boolean ok = false; 35 | HttpURLConnection connection = null; 36 | Proxy proxy = null; 37 | 38 | try { 39 | URL url = new URL(urlString); 40 | if (Config.getFAADMZProxyHost() != null && (! EMPTY_STRING.equals(Config.getFAADMZProxyHost())) ) { 41 | int port = Integer.parseInt(Config.getFAADMZProxyPort()); 42 | InetSocketAddress proxyAddress = new InetSocketAddress(Config.getFAADMZProxyHost(), port); 43 | proxy = new Proxy(Proxy.Type.HTTP, proxyAddress); 44 | } 45 | 46 | if (proxy != null) { 47 | connection = (HttpURLConnection) url.openConnection(proxy); 48 | } 49 | else { 50 | connection = (HttpURLConnection) url.openConnection(); 51 | } 52 | 53 | connection.setRequestMethod("HEAD"); 54 | int responseCode = connection.getResponseCode(); 55 | if (responseCode == 200 || responseCode == 302) { 56 | ok = true; 57 | } 58 | else { 59 | logger.warn("URL HEAD check returned response code "+responseCode+" for url "+url.toExternalForm()); 60 | } 61 | } 62 | catch (IOException eio) { 63 | logger.error("HEAD heck failed!", eio); 64 | logger.error(eio.getMessage()); 65 | ok = false; 66 | } 67 | 68 | if (connection != null) 69 | connection.disconnect(); 70 | 71 | return ok; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/util/URLCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.util; 15 | 16 | import java.util.Date; 17 | import java.util.GregorianCalendar; 18 | import java.util.HashSet; 19 | import java.util.TimeZone; 20 | 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | 24 | public class URLCache { 25 | private static final Logger logger = LoggerFactory.getLogger(URLCache.class); 26 | private static URLCache instance; 27 | private static HashSet cache; 28 | private static Date lastFlush; 29 | 30 | private URLCache () { 31 | flush(); 32 | } 33 | 34 | public static synchronized URLCache getInstance() { 35 | if(instance == null) { 36 | instance = new URLCache(); 37 | URLCache.lastFlush = new Date (System.currentTimeMillis()); 38 | } 39 | 40 | if (instance.isUpdateRequired()) { 41 | URLCache.flush(); 42 | } 43 | return instance; 44 | } 45 | 46 | public boolean contains (String url) { 47 | return cache.contains(url); 48 | } 49 | 50 | public static void addUrl (String url) { 51 | if (URLCache.cache == null) { 52 | URLCache.cache = new HashSet<>(); 53 | } 54 | 55 | cache.add(url); 56 | } 57 | 58 | public static synchronized void flush () { 59 | logger.info("URL cache is being flushed."); 60 | if (URLCache.cache == null) { 61 | URLCache.cache = new HashSet<>(); 62 | } 63 | 64 | cache.clear(); 65 | URLCache.lastFlush = new Date (System.currentTimeMillis()); 66 | } 67 | 68 | private boolean isUpdateRequired () { 69 | 70 | CycleDateUtil cdu = new CycleDateUtil(); 71 | 72 | GregorianCalendar cycle = new GregorianCalendar(TimeZone.getDefault()); 73 | GregorianCalendar lastRefresh = new GregorianCalendar(TimeZone.getDefault()); 74 | 75 | lastRefresh.setTime(URLCache.lastFlush); 76 | cycle.setTime(cdu.getCurrentCycle()); 77 | 78 | if (cycle.after(lastRefresh)) { 79 | logger.info("URL cache requires a refresh"); 80 | return true; 81 | } 82 | 83 | return false; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/path/PathElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.path; 15 | 16 | /** 17 | * This is a convenience class to hold the element of a URL such as a folder, directory, or file 18 | * @author FAA 19 | * 20 | */ 21 | public class PathElement { 22 | 23 | private String pathName; 24 | private boolean isFile; 25 | 26 | /** 27 | * Create a default path element with a directory 28 | * @param dir 29 | */ 30 | public PathElement (String dir) { 31 | this.pathName = dir; 32 | this.isFile = false; 33 | } 34 | 35 | /** 36 | * The null constructor where the path element name can be set later 37 | */ 38 | public PathElement () { 39 | this.pathName = ""; 40 | this.isFile = false; 41 | } 42 | 43 | /** 44 | * Get the path element name 45 | * @return the name of the path element 46 | */ 47 | public String getPathElement () { 48 | return pathName; 49 | } 50 | 51 | /** 52 | * Set or reset the path element name to some string 53 | * @param pe the string name of the path element to set 54 | * @return the path element to enable chaining of sets 55 | */ 56 | public PathElement setPathElement (String pe) { 57 | this.pathName = pe; 58 | return this; 59 | } 60 | 61 | /** 62 | * The file is the last part of the path element. Setting this marks the path as complete and no further additions to the path are allowed. 63 | */ 64 | public void setFile() { 65 | isFile = true; 66 | } 67 | 68 | /** 69 | * Returns true if this particular path element is a file marking the end of the path 70 | * @return true if a file, false otherwise 71 | */ 72 | public boolean isFile () { 73 | return isFile; 74 | } 75 | 76 | /** 77 | * Marks this path element as a directory so additional path elements can be created and added to a path 78 | */ 79 | public void setDirectory () { 80 | isFile = false; 81 | } 82 | 83 | /** 84 | * Returns true if this particular path element is a directory 85 | * @return true if a directory 86 | */ 87 | public boolean isDirectory() { 88 | return ! isFile; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/cycle/ChartCycleElementsJson.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.cycle; 15 | 16 | import java.util.Date; 17 | 18 | public class ChartCycleElementsJson { 19 | private String chart_cycle_period_code; 20 | private String chart_cycle_type_code; 21 | private Date chart_effective_date; 22 | private String chart_cycle_number; 23 | private String query_date; 24 | private String chart_city_name; 25 | 26 | public ChartCycleElementsJson () { 27 | /* 28 | chart_cycle_period_code = ""; 29 | chart_cycle_type_code = ""; 30 | chart_effective_date = new Date (System.currentTimeMillis()); 31 | chart_cycle_number = ""; 32 | query_date = ""; 33 | chart_city_name = ""; 34 | */ 35 | } 36 | 37 | public String getChart_cycle_period_code() { 38 | return chart_cycle_period_code; 39 | } 40 | public void setChart_cycle_period_code(String chart_cycle_period_code) { 41 | this.chart_cycle_period_code = chart_cycle_period_code; 42 | } 43 | public String getChart_cycle_type_code() { 44 | return chart_cycle_type_code; 45 | } 46 | public void setChart_cycle_type_code(String chart_cycle_type_code) { 47 | this.chart_cycle_type_code = chart_cycle_type_code; 48 | } 49 | public Date getChart_effective_date() { 50 | if (chart_effective_date == null) 51 | return new Date(System.currentTimeMillis()); 52 | 53 | return new Date (chart_effective_date.getTime()); 54 | } 55 | public void setChart_effective_date(Date chart_effective_date) { 56 | if (chart_effective_date == null) 57 | return; 58 | 59 | this.chart_effective_date = new Date(chart_effective_date.getTime()); 60 | } 61 | public String getChart_cycle_number() { 62 | return chart_cycle_number; 63 | } 64 | public void setChart_cycle_number(String chart_cycle_number) { 65 | this.chart_cycle_number = chart_cycle_number; 66 | } 67 | public String getQuery_date() { 68 | return query_date; 69 | } 70 | public void setQuery_date(String query_date) { 71 | this.query_date = query_date; 72 | } 73 | public String getChart_city_name() { 74 | return chart_city_name; 75 | } 76 | public void setChart_city_name(String chart_city_name) { 77 | this.chart_city_name = chart_city_name; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/util/TACSpecialCase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.util; 15 | 16 | import java.util.Locale; 17 | 18 | /** 19 | * This class covers special cases of TAC files that don't conform to naming conventions such as Denver-Colorado Springs being shortened to Denver in the file name. 20 | * As naming conventions become more consistent, it is hoped that this class is deprecated and no longer required. 21 | * @author FAA 22 | * 23 | */ 24 | public class TACSpecialCase { 25 | 26 | private static final int PUERTO_RICO_VI = 0; 27 | private static final int DENVER_COLORADO_SPRINGS = 1; 28 | private static final int ANCHORAGE_FAIRBANKS = 3; 29 | private static final String ZIP = ".zip"; 30 | 31 | private TACSpecialCase () { } 32 | 33 | public static String getTACFileName (int specialCase, String editionNumber, String format) { 34 | 35 | if ("pdf".equalsIgnoreCase(format)) { 36 | switch (specialCase) { 37 | case DENVER_COLORADO_SPRINGS: 38 | return "Denver_TAC_"+editionNumber+"_P.pdf"; 39 | 40 | case ANCHORAGE_FAIRBANKS: 41 | return "Anchorage-Fairbanks_TAC_"+editionNumber+"_P.pdf"; 42 | 43 | case PUERTO_RICO_VI: 44 | return "Puerto_Rico-VI_TAC_"+editionNumber+"_P.pdf"; 45 | 46 | default: 47 | break; 48 | 49 | } 50 | } 51 | else if ("tiff".equalsIgnoreCase(format)) { 52 | switch (specialCase) { 53 | case DENVER_COLORADO_SPRINGS: 54 | return "Denver_TAC_"+editionNumber+ZIP; 55 | 56 | case ANCHORAGE_FAIRBANKS: 57 | return "Anchorage-Fairbanks_TAC_"+editionNumber+ZIP; 58 | 59 | case PUERTO_RICO_VI: 60 | return "Puerto_Rico-VI_TAC_"+editionNumber+ZIP; 61 | 62 | default: 63 | break; 64 | 65 | } 66 | } 67 | 68 | return ""; 69 | } 70 | 71 | public static int getSpecialCase (String geoname) { 72 | 73 | if (geoname.toLowerCase(Locale.ENGLISH).startsWith("puerto")) { 74 | return PUERTO_RICO_VI; 75 | } 76 | 77 | if (geoname.toLowerCase(Locale.ENGLISH).startsWith("denver")) { 78 | return DENVER_COLORADO_SPRINGS; 79 | } 80 | 81 | if (geoname.toLowerCase(Locale.ENGLISH).startsWith("anchorage")) { 82 | return ANCHORAGE_FAIRBANKS; 83 | } 84 | 85 | return -1; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/bootstrap/TPPVolume.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.bootstrap; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | /** 20 | * This is a convenience class to hold the TPP volumes and verify membership in the volume list 21 | * @author FAA 22 | * 23 | */ 24 | public class TPPVolume { 25 | 26 | // Make the list a static final so it becomes immutable and cannot be set by another class. 27 | // Items within the list can be added and removed by this class only 28 | private static final List volumes = new ArrayList <> (); 29 | 30 | // A private null constructor to protect the volume list 31 | private TPPVolume () { } 32 | 33 | static { 34 | TPPVolume.initVolumes(); 35 | } 36 | 37 | /** 38 | * Get the list TPP volumes contained within the reference data set 39 | * @return a new list TPP volumes 40 | */ 41 | public static List getVolumeList () { 42 | // We don't want to return our list here because it is static and we don't want someone adding 43 | // new items to the list which could cause a memory leak or other bugs. 44 | return new ArrayList <> (volumes); 45 | } 46 | 47 | private static void initVolumes () { 48 | volumes.add("NE-1"); 49 | volumes.add("NE-2"); 50 | volumes.add("NE-3"); 51 | volumes.add("NE-4"); 52 | volumes.add("SE-1"); 53 | volumes.add("SE-2"); 54 | volumes.add("SE-3"); 55 | volumes.add("SE-4"); 56 | volumes.add("SC-1"); 57 | volumes.add("SC-2"); 58 | volumes.add("SC-3"); 59 | volumes.add("SC-4"); 60 | volumes.add("SC-5"); 61 | volumes.add("EC-1"); 62 | volumes.add("EC-2"); 63 | volumes.add("EC-3"); 64 | volumes.add("NC-1"); 65 | volumes.add("NC-2"); 66 | volumes.add("NC-3"); 67 | volumes.add("SW-1"); 68 | volumes.add("SW-2"); 69 | volumes.add("SW-3"); 70 | volumes.add("SW-4"); 71 | volumes.add("NW-1"); 72 | volumes.add("AK-1"); 73 | volumes.add("PC-1"); 74 | } 75 | /** 76 | * Determine if a volume passed to this method is one of the valid TPP volumes 77 | * @param volumeName the name of the volume to be checked and verified 78 | * @return true if the volume is valid, false otherwise 79 | */ 80 | public static boolean isValidVolumeName (String volumeName) { 81 | return TPPVolume.volumes.contains(volumeName); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/json/SupplementMetadata.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.json; 15 | 16 | /** 17 | * Supplement Metadata pojo object. 18 | * 19 | */ 20 | 21 | public class SupplementMetadata { 22 | 23 | protected String state; 24 | protected String aptname; 25 | protected String aptcity; 26 | protected String aptid; 27 | protected String pdf; 28 | protected String navidname; 29 | protected String chartDate; 30 | protected String volumeAbbreviation; 31 | protected String volumeName; 32 | 33 | public SupplementMetadata () { 34 | state = ""; 35 | aptname = ""; 36 | aptcity = ""; 37 | aptid = ""; 38 | pdf = ""; 39 | navidname = ""; 40 | chartDate = ""; 41 | volumeAbbreviation = ""; 42 | volumeName = ""; 43 | } 44 | 45 | public String getState() { 46 | return state; 47 | } 48 | 49 | public void setState(String value) { 50 | this.state = value; 51 | } 52 | 53 | public String getAptname() { 54 | return aptname; 55 | } 56 | 57 | public void setAptname(String value) { 58 | this.aptname = value; 59 | } 60 | 61 | public String getAptcity() { 62 | return aptcity; 63 | } 64 | 65 | public void setAptcity(String value) { 66 | this.aptcity = value; 67 | } 68 | 69 | public String getAptid() { 70 | return aptid; 71 | } 72 | 73 | public void setAptid(String value) { 74 | this.aptid = value; 75 | } 76 | 77 | public String getPdf() { 78 | return pdf; 79 | } 80 | 81 | public void setPdf(String value) { 82 | this.pdf = value; 83 | } 84 | 85 | public String getNavidname() { 86 | return navidname; 87 | } 88 | 89 | public void setNavidname(String value) { 90 | this.navidname = value; 91 | } 92 | 93 | public String getChartDate() { 94 | return chartDate; 95 | } 96 | 97 | public void setChartDate(String value) { 98 | this.chartDate = value; 99 | } 100 | 101 | public String getVolumeAbbreviation() { 102 | return volumeAbbreviation; 103 | } 104 | 105 | public void setVolumeAbbreviation(String value) { 106 | this.volumeAbbreviation = value; 107 | } 108 | 109 | public String getVolumeName() { 110 | return volumeName; 111 | } 112 | 113 | public void setVolumeName(String value) { 114 | this.volumeName = value; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/SectionalChartTableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertTrue; 17 | 18 | import java.text.ParseException; 19 | import java.text.SimpleDateFormat; 20 | 21 | import org.junit.Test; 22 | 23 | import gov.faa.ait.apra.cycle.ChartCycleElementsJson; 24 | import gov.faa.ait.apra.cycle.ChartCycleData; 25 | import gov.faa.ait.apra.util.ChartInfoTable; 26 | import gov.faa.ait.apra.util.ChartInfoTableKey; 27 | 28 | public class SectionalChartTableTest { 29 | 30 | // @Test 31 | // public void testLoad() { 32 | // SectionalChartCycleJson jsonData = buildJson(); 33 | // SectionalChartTable table = new SectionalChartTable(jsonData); 34 | // fail("Not yet implemented"); 35 | // } 36 | 37 | @Test 38 | public void testContainsKey() throws ParseException { 39 | ChartCycleData jsonData = buildJson(); 40 | ChartInfoTable table = new ChartInfoTable(jsonData); 41 | ChartInfoTableKey key = new ChartInfoTableKey("ALBUQUERQUE", "CURRENT", "SECTIONAL"); 42 | assertTrue("Expected Key not found", table.containsKey(key)); 43 | ChartInfoTableKey key2 = new ChartInfoTableKey("ALBUQUERQUE", "NEXT", "SECTIONAL"); 44 | assertTrue("Expected Key not found", table.containsKey(key2)); 45 | 46 | } 47 | 48 | private ChartCycleData buildJson() throws ParseException { 49 | ChartCycleData cc = new ChartCycleData(); 50 | //SimpleDateFormat sdfUS = new SimpleDateFormat("MM/dd/yyyy"); 51 | cc.setName("SECTIONAL"); 52 | ChartCycleElementsJson element = buildElement("Albuquerque", "current", "Sectional"); 53 | ChartCycleElementsJson[] elemArray = new ChartCycleElementsJson[2]; 54 | elemArray[0] = element; 55 | ChartCycleElementsJson element2 = buildElement("Albuquerque", "next", "Sectional"); 56 | elemArray[1] = element2; 57 | cc.setElements(elemArray); 58 | return cc; 59 | } 60 | 61 | private ChartCycleElementsJson buildElement(String city, String period, String type) throws ParseException { 62 | SimpleDateFormat sdfISO = new SimpleDateFormat("yyyy-dd-MM"); 63 | ChartCycleElementsJson element = new ChartCycleElementsJson(); 64 | element.setChart_city_name(city); 65 | element.setChart_cycle_number("97"); 66 | element.setChart_cycle_period_code(period); 67 | element.setChart_cycle_type_code(type); 68 | element.setChart_effective_date(sdfISO.parse("2016-04-28")); 69 | element.setQuery_date("2016-06-16"); 70 | return element; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/DERSTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | import static org.junit.Assert.fail; 19 | 20 | import javax.ws.rs.core.Response; 21 | 22 | import org.junit.Test; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | import gov.faa.ait.apra.api.DigitalEnrouteSupplementCharts; 27 | import gov.faa.ait.apra.cycle.ChartCycleClient; 28 | import gov.faa.ait.apra.jaxb.ProductSet; 29 | 30 | public class DERSTest { 31 | private DigitalEnrouteSupplementCharts ders; 32 | private static final Logger logger = LoggerFactory.getLogger(DERSTest.class); 33 | 34 | public DERSTest () { 35 | ChartCycleClient client = new ChartCycleClient(); 36 | client.forceUpdate(); 37 | } 38 | 39 | @Test 40 | public void testCurrentRelease() { 41 | ders = new DigitalEnrouteSupplementCharts(); 42 | Response ps = ders.getDERSRelease("current"); 43 | int code = ps.getStatus(); 44 | assertEquals(404, code); 45 | } 46 | 47 | @Test 48 | public void testNextRelease() { 49 | ders = new DigitalEnrouteSupplementCharts(); 50 | Response ps = ders.getDERSRelease("next"); 51 | int code = ps.getStatus(); 52 | 53 | // Have to allow for either a positive response or a not found due to the AJV release cycle. A "next" edition may 54 | // only be published 20 days in advance. Therefore, there is a time period when we may ask for "next", but it really hasn't 55 | // been put on the web site yet 56 | if (! (code == 200 || code == 404) ) { 57 | fail(); 58 | } 59 | } 60 | 61 | @Test 62 | public void testCurrentEdition() { 63 | ders = new DigitalEnrouteSupplementCharts(); 64 | Response ps = ders.getDERSEdition("current"); 65 | int code = ps.getStatus(); 66 | assertEquals(404, code); 67 | } 68 | 69 | @Test 70 | public void testNextEdition() { 71 | ders = new DigitalEnrouteSupplementCharts(); 72 | Response ps = ders.getDERSEdition("next"); 73 | int code = ps.getStatus(); 74 | assertEquals(404, code); 75 | } 76 | 77 | @Test 78 | public void testBadRelease() { 79 | ders = new DigitalEnrouteSupplementCharts(); 80 | Response ps = ders.getDERSRelease("bad"); 81 | int code = ps.getStatus(); 82 | assertEquals(404, code); 83 | } 84 | 85 | @Test 86 | public void testBadEdition() { 87 | ders = new DigitalEnrouteSupplementCharts(); 88 | Response ps = ders.getDERSRelease("bad"); 89 | int code = ps.getStatus(); 90 | assertEquals(404, code); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | gov.faa.ait.apra.api.DownloadServiceApp 7 | 8 | org.glassfish.jersey.servlet.ServletContainer 9 | 10 | javax.ws.rs.Application 11 | gov.faa.ait.apra.api.DownloadServiceApp 12 | 13 | 14 | jersey.config.server.provider.packages 15 | io.swagger.jaxrs.listing, gov.faa.ait.apra.api 16 | 17 | 18 | com.sun.jersey.config.feature.Debug 19 | true 20 | 21 | 35 | 1 36 | 37 | 38 | 39 | gov.faa.ait.apra.api.DownloadServiceApp 40 | /* 41 | 42 | 43 | 44 | DefaultJaxrsConfig 45 | io.swagger.jaxrs.config.DefaultJaxrsConfig 46 | 47 | api.version 48 | 2.0.0 49 | 50 | 51 | swagger.api.title 52 | Aeronautic Product Release API 53 | 54 | 55 | swagger.api.basepath 56 | https://soa.smext.faa.gov/apra 57 | 58 | 2 59 | 60 | 61 | 62 | APRA Security 63 | 64 | APRAInfo 65 | /foo/* 66 | GET 67 | 68 | 69 | * 70 | 71 | 72 | NONE 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/NASRTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | 19 | import org.junit.Test; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | 23 | import gov.faa.ait.apra.api.NASRSubscription; 24 | import gov.faa.ait.apra.jaxb.ProductSet; 25 | 26 | public class NASRTest { 27 | private final static Logger logger = LoggerFactory.getLogger(NASRTest.class); 28 | 29 | @Test 30 | public void testDefaults() { 31 | NASRSubscription nasr = new NASRSubscription(); 32 | ProductSet ps = (ProductSet) nasr.getNASRSubscription(null).getEntity(); 33 | logger.info("NASR default test return url of "+ps.getEdition().get(0).getProduct().getUrl()); 34 | int code = ps.getStatus().getCode().intValue(); 35 | assertEquals(200, code); 36 | } 37 | 38 | @Test 39 | public void testCurrentRelease() { 40 | NASRSubscription nasr = new NASRSubscription(); 41 | ProductSet ps = (ProductSet) nasr.getNASRSubscription("current").getEntity(); 42 | logger.info("NASR default test return url of "+ps.getEdition().get(0).getProduct().getUrl()); 43 | int code = ps.getStatus().getCode().intValue(); 44 | assertEquals(200, code); 45 | } 46 | 47 | @Test 48 | public void testNextRelease() { 49 | NASRSubscription nasr = new NASRSubscription(); 50 | ProductSet ps = (ProductSet) nasr.getNASRSubscription("next").getEntity(); 51 | logger.info("NASR default test return url of "+ps.getEdition().get(0).getProduct().getUrl()); 52 | } 53 | 54 | @Test 55 | public void testDefaultEdition() { 56 | NASRSubscription nasr = new NASRSubscription(); 57 | ProductSet ps = (ProductSet) nasr.getNASREdition(null).getEntity(); 58 | int code = ps.getStatus().getCode().intValue(); 59 | assertEquals(200, code); 60 | } 61 | 62 | @Test 63 | public void testCurrentEdition() { 64 | NASRSubscription nasr = new NASRSubscription(); 65 | ProductSet ps = (ProductSet) nasr.getNASREdition("current").getEntity(); 66 | int code = ps.getStatus().getCode().intValue(); 67 | assertEquals(200, code); 68 | } 69 | 70 | @Test 71 | public void testNextEdition() { 72 | NASRSubscription nasr = new NASRSubscription(); 73 | ProductSet ps = (ProductSet) nasr.getNASRSubscription("next").getEntity(); 74 | int code = ps.getStatus().getCode().intValue(); 75 | assertEquals(200, code); 76 | } 77 | 78 | @Test 79 | public void testInvalidEdition() { 80 | NASRSubscription nasr = new NASRSubscription(); 81 | ProductSet ps = (ProductSet) nasr.getNASRSubscription("Invalid").getEntity(); 82 | int code = ps.getStatus().getCode().intValue(); 83 | assertEquals(400, code); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/api/ProductApiListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.api; 15 | 16 | import org.glassfish.jersey.server.monitoring.ApplicationEvent; 17 | import org.glassfish.jersey.server.monitoring.ApplicationEventListener; 18 | import org.glassfish.jersey.server.monitoring.RequestEvent; 19 | import org.glassfish.jersey.server.monitoring.RequestEventListener; 20 | import org.apache.logging.log4j.ThreadContext; 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | 24 | /** 25 | * A product api listener class for all JAX-RS events 26 | * @author FAA 27 | * 28 | */ 29 | public class ProductApiListener implements ApplicationEventListener { 30 | private static final Logger logger = LoggerFactory.getLogger(ProductApiListener.class); 31 | private volatile int requestCount = 0; 32 | @Override 33 | public void onEvent (ApplicationEvent appEvent) { 34 | switch (appEvent.getType()) { 35 | case INITIALIZATION_FINISHED: 36 | logger.info("FAA aeronautical product release API (APRA) started. Ready to service requests."); 37 | break; 38 | default: 39 | break; 40 | } 41 | } 42 | 43 | @Override 44 | public RequestEventListener onRequest (RequestEvent requestEvent) { 45 | requestCount++; 46 | return new ProductApiEventListener(requestCount); 47 | } 48 | 49 | /** 50 | * The API event listener for APRA. Current events which are captured and processed are the RESOURCE_START_METHOD and FINISHED events 51 | * @author Martin Hile 52 | * 53 | */ 54 | public static class ProductApiEventListener implements RequestEventListener { 55 | 56 | private final int requestNumber; 57 | private final long startTime; 58 | private static final Logger logger = LoggerFactory.getLogger(ProductApiListener.class); 59 | 60 | /** 61 | * This event listener records the time spent processing a request to APRA 62 | * @param requestNumber the number of the request which is output to the log file. Incremented by 1 for each request processed 63 | */ 64 | public ProductApiEventListener (int requestNumber) { 65 | this.requestNumber = requestNumber; 66 | this.startTime = System.currentTimeMillis(); 67 | } 68 | 69 | @Override 70 | public void onEvent (RequestEvent event) { 71 | switch (event.getType()) { 72 | case RESOURCE_METHOD_START: 73 | // Output the start of a resource event so we get a request number logged 74 | ThreadContext.put("ID", "APRA-"+Integer.toString(requestNumber)); 75 | logger.info("Resource method "+event.getUriInfo().getMatchedResourceMethod().getHttpMethod()+" started for request "+requestNumber); 76 | break; 77 | case FINISHED: 78 | // Mark the finish of the processing with the duration spent fulfilling the request. Useful for debugging performance problems. 79 | logger.info("Request "+requestNumber+" finished. Processing time "+ (System.currentTimeMillis() - startTime) + " ms."); 80 | ThreadContext.clearAll(); 81 | break; 82 | default: 83 | break; 84 | } 85 | } 86 | 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/ChartCycleTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertNotNull; 18 | 19 | import java.text.ParseException; 20 | import java.text.SimpleDateFormat; 21 | import java.util.Arrays; 22 | import java.util.Date; 23 | import java.util.List; 24 | 25 | import org.junit.Before; 26 | import org.junit.Test; 27 | import org.junit.runner.RunWith; 28 | import org.junit.runners.Parameterized; 29 | 30 | import gov.faa.ait.apra.cycle.ChartCycleClient; 31 | import gov.faa.ait.apra.cycle.ChartCycleElementsJson; 32 | 33 | @RunWith(Parameterized.class) 34 | public class ChartCycleTest { 35 | private Date checkDate; 36 | private Integer expectedCycle; 37 | private ChartCycleClient client; 38 | 39 | public ChartCycleTest (Date date, Integer cycle) { 40 | this.checkDate = new Date(date.getTime()); 41 | this.expectedCycle = cycle; 42 | } 43 | 44 | @Before 45 | public void initialize() { 46 | client = new ChartCycleClient(); 47 | } 48 | 49 | @Parameterized.Parameters 50 | public static List cycleNumbers () { 51 | SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); 52 | Object [] [] params = null; 53 | 54 | try { 55 | params = new Object [] [] { 56 | {formatter.parse("06/17/2016"), Integer.valueOf(3)}, 57 | {formatter.parse("10/13/2016"), Integer.valueOf(5)}, 58 | {formatter.parse("11/10/2016"), Integer.valueOf(6)}, 59 | {formatter.parse("01/01/2017"), Integer.valueOf(6)}, 60 | {formatter.parse("12/25/2016"), Integer.valueOf(6)}, 61 | {formatter.parse("01/05/2017"), Integer.valueOf(1)}, 62 | {formatter.parse("02/03/2017"), Integer.valueOf(1)}, 63 | {formatter.parse("06/14/2017"), Integer.valueOf(3)}, 64 | {formatter.parse("09/15/2017"), Integer.valueOf(5)}, 65 | {formatter.parse("11/09/2017"), Integer.valueOf(6)} 66 | }; 67 | } 68 | catch (ParseException e) { 69 | params = new Object [] [] { 70 | {new Date(System.currentTimeMillis()), Integer.valueOf(1) } 71 | }; 72 | } 73 | 74 | return Arrays.asList(params); 75 | } 76 | 77 | @Test 78 | public void testChartCycle() { 79 | client.getChartCycle(checkDate, true); 80 | String cycleNumber = client.getCurrent56DayCycle().getChart_cycle_number(); 81 | assertEquals (expectedCycle.intValue(), Integer.parseInt(cycleNumber)); 82 | } 83 | 84 | @Test 85 | public void getCurrent28DayCycle () { 86 | ChartCycleElementsJson cc = client.getCurrent28DayCycle(); 87 | assertNotNull(cc); 88 | } 89 | 90 | @Test 91 | public void getNext28DayCycle () { 92 | ChartCycleElementsJson cc = client.getNext28DayCycle(); 93 | assertNotNull(cc); 94 | } 95 | 96 | @Test 97 | public void getCurrent56DayCycle () { 98 | ChartCycleElementsJson cc = client.getCurrent56DayCycle(); 99 | assertNotNull(cc); 100 | } 101 | 102 | @Test 103 | public void getNext56DayCycle () { 104 | ChartCycleElementsJson cc = client.getNext56DayCycle(); 105 | assertNotNull(cc); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/api/management/ManagementControl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.api.management; 15 | 16 | import javax.ws.rs.GET; 17 | import javax.ws.rs.Path; 18 | import javax.ws.rs.Produces; 19 | import javax.ws.rs.core.MediaType; 20 | 21 | import gov.faa.ait.apra.bootstrap.Config; 22 | import gov.faa.ait.apra.cycle.ChartCycleClient; 23 | import gov.faa.ait.apra.cycle.TACCycleClient; 24 | import gov.faa.ait.apra.util.URLCache; 25 | import gov.faa.ait.apra.cycle.VFRChartCycleClient; 26 | import gov.faa.ait.apra.cycle.WallPlanningChartCycleClient; 27 | 28 | @Path("/management") 29 | /** 30 | * This class provides management and control functions to assist with configuration reload, cache flush, start, stop, and health 31 | * @author FAA 32 | * 33 | */ 34 | public class ManagementControl { 35 | private static int mode = 1; 36 | 37 | @Path("/health") 38 | @GET 39 | @Produces(MediaType.TEXT_PLAIN) 40 | /** 41 | * Return the status of the application. This is the healthcheck URL for the application. 42 | * @return the string ServerOK or ServerDown depending on the state of the application 43 | */ 44 | public String getStatus () { 45 | if (ManagementControl.mode == 0) 46 | return "ServerDown"; 47 | 48 | return "ServerOK"; 49 | } 50 | 51 | @Path("/stop") 52 | @GET 53 | @Produces(MediaType.TEXT_PLAIN) 54 | 55 | /** 56 | * Stop the service. This will cause the service healthcheck to return "ServerDown" indicating to the load balancer that the service is offline 57 | * @return the String ServerDown 58 | */ 59 | public static String stop() { 60 | ManagementControl.mode = 0; 61 | return "ServerDown"; 62 | } 63 | 64 | @Path("/start") 65 | @GET 66 | @Produces(MediaType.TEXT_PLAIN) 67 | /** 68 | * Start or restart the service. This will cause the healthcheck to return "ServerOK" indicating to the load balancer that the service is online 69 | * @return the String ServerOK 70 | */ 71 | public static String start() { 72 | ManagementControl.mode = 1; 73 | return "ServerOK"; 74 | } 75 | 76 | @Path("/flush") 77 | @GET 78 | @Produces(MediaType.TEXT_PLAIN) 79 | /** 80 | * This method flushes the cache for the ChartCycleClient, TAC cycle, VFR cycle, and Wall Planning cycle 81 | * @return the string "Cycle reload complete" 82 | */ 83 | public String refresh() { 84 | ChartCycleClient cycleClient = new ChartCycleClient(); 85 | cycleClient.forceUpdate(); 86 | TACCycleClient tacCycleClient = new TACCycleClient(); 87 | tacCycleClient.forceUpdate(); 88 | VFRChartCycleClient vfrClient = new VFRChartCycleClient(); 89 | vfrClient.forceUpdate(); 90 | WallPlanningChartCycleClient wpClient = new WallPlanningChartCycleClient(); 91 | wpClient.forceUpdate(); 92 | 93 | URLCache.getInstance().flush(); 94 | 95 | return "Cycle Reload Complete"; 96 | } 97 | 98 | @Path("/config") 99 | @GET 100 | @Produces(MediaType.TEXT_PLAIN) 101 | /** 102 | * This causes the application to reload its configuration from disk. This reloads the properties file without an app restart 103 | * @return the string Config Reload Complete 104 | */ 105 | public String reloadConfig() { 106 | Config.loadConfig(); 107 | return "Config Reload Complete"; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/IFREnrouteFunctionalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | 19 | import javax.ws.rs.core.Response; 20 | 21 | import org.junit.Test; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | 25 | import gov.faa.ait.apra.api.IFREnrouteCharts; 26 | import gov.faa.ait.apra.bootstrap.ErrorCodes; 27 | import gov.faa.ait.apra.jaxb.ProductSet; 28 | 29 | public class IFREnrouteFunctionalTest { 30 | private static final Logger logger = LoggerFactory 31 | .getLogger(IFREnrouteFunctionalTest.class); 32 | private static final String CURRENT = "CURRENT"; 33 | private static final String TIFF = "TIFF"; 34 | private static final String CARIBBEAN = "CARIBBEAN"; 35 | private static final String LOW = "LOW"; 36 | private IFREnrouteCharts enroute; 37 | 38 | private String editions[] = {"current"}; 39 | private String formats[] = {"pdf", "tiff" }; 40 | private String geos[] = {"us", "alaska" }; 41 | private String alts[] = {"low", "high" }; 42 | 43 | public IFREnrouteFunctionalTest () { 44 | enroute = new IFREnrouteCharts(); 45 | } 46 | 47 | @Test 48 | public void testProductRelese() { 49 | 50 | for (String edition : editions) { 51 | for (String format : formats) { 52 | for (String geo : geos) { 53 | for (String alt : alts) { 54 | logger.info("Edition: current " + "format: " + format 55 | + " geo: " + geo + " alt: " + alt); 56 | ProductSet ps = (ProductSet) enroute.getIFREnrouteRelease(edition, 57 | format, geo, alt).getEntity(); 58 | int code = ps.getStatus().getCode().intValue(); 59 | if (code == 200) { 60 | logger.info("IFREnroute Product Relese test return url " 61 | + ps.getEdition().get(0).getProduct() 62 | .getUrl()); 63 | assertTrue(VerifyValues.verifyURL(ps.getEdition() 64 | .get(0).getProduct().getUrl())); 65 | 66 | } else { 67 | assertEquals(code, 404); 68 | } 69 | } 70 | } 71 | } 72 | } 73 | } 74 | 75 | @Test 76 | public void testBadSet() { 77 | enroute = new IFREnrouteCharts(); 78 | Response resp = enroute.getIFREnrouteRelease(CURRENT, TIFF, CARIBBEAN, LOW); 79 | assertEquals(404, resp.getStatus()); 80 | ProductSet ps = (ProductSet) resp.getEntity(); 81 | assertEquals(Integer.valueOf(404), ps.getStatus().getCode()); 82 | assertEquals(ErrorCodes.ERROR_404, ps.getStatus().getMessage()); 83 | assertEquals(0, ps.getEdition().size()); 84 | } 85 | 86 | public void testProductedition() { 87 | 88 | enroute = new IFREnrouteCharts(); 89 | for (String edition : editions) { 90 | for (String format : formats) { 91 | for (String geo : geos) { 92 | for (String alt : alts) { 93 | logger.info("Edition: current " + "format: " + format 94 | + " geo: " + geo + " alt: " + alt); 95 | ProductSet ps = (ProductSet) enroute.getIFREnrouteEdition(edition).getEntity(); 96 | int code = ps.getStatus().getCode().intValue(); 97 | if (code == 200) { 98 | assertEquals(code, 200); 99 | } else { 100 | assertEquals(code, 404); 101 | } 102 | } 103 | } 104 | } 105 | } 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/SectionalChartClientTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import java.text.ParseException; 19 | import java.text.SimpleDateFormat; 20 | import java.util.Arrays; 21 | import java.util.Date; 22 | import java.util.List; 23 | 24 | import org.junit.Before; 25 | import org.junit.Test; 26 | import org.junit.runner.RunWith; 27 | import org.junit.runners.Parameterized; 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | 31 | import gov.faa.ait.apra.cycle.ChartCycleElementsJson; 32 | import gov.faa.ait.apra.cycle.ChartCycleData; 33 | import gov.faa.ait.apra.util.ChartInfoTable; 34 | import gov.faa.ait.apra.util.ChartInfoTableKey; 35 | import gov.faa.ait.apra.util.TableChartClient; 36 | 37 | @RunWith(Parameterized.class) 38 | public class SectionalChartClientTest { 39 | 40 | //private static final Logger logger = LoggerFactory.getLogger(SectionalChartClientTest.class); 41 | 42 | //private static final String CURRENT_CODE = "CURRENT"; 43 | 44 | private TableChartClient client; 45 | private Date targetDate; 46 | private String cityKey; 47 | private String editionKey; 48 | private String typeKey; 49 | private Integer expectedVersion; 50 | 51 | public SectionalChartClientTest(Date targetDate, String city, String edition, String type, Integer cycle) { 52 | this.targetDate = new Date(targetDate.getTime()); 53 | this.cityKey = city; 54 | this.editionKey = edition; 55 | this.typeKey = type; 56 | this.expectedVersion = cycle; 57 | } 58 | 59 | @Before 60 | public void init() { 61 | this.client = new TableChartClient(); 62 | } 63 | 64 | @Parameterized.Parameters 65 | public static List cycleNumbers () { 66 | //ArrayList arrayList = new ArrayList (); 67 | SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); 68 | Object [] [] params = null; 69 | 70 | try { 71 | params = new Object [] [] { 72 | {formatter.parse("06/15/2016"), "ALBUQUERQUE", "CURRENT", "SECTIONAL", Integer.valueOf(97)}, 73 | {formatter.parse("06/15/2016"), "ALBUQUERQUE", "NEXT", "SECTIONAL", Integer.valueOf(98)} 74 | /* 75 | {formatter.parse("11/10/2016"), new Integer(6)}, 76 | {formatter.parse("01/01/2017"), new Integer(6)}, 77 | {formatter.parse("12/25/2016"), new Integer(6)}, 78 | {formatter.parse("01/05/2017"), new Integer(1)}, 79 | {formatter.parse("02/03/2017"), new Integer(1)}, 80 | {formatter.parse("06/14/2017"), new Integer(3)}, 81 | {formatter.parse("09/15/2017"), new Integer(5)}, 82 | {formatter.parse("11/09/2017"), new Integer(6)} 83 | 84 | */ 85 | }; 86 | } 87 | catch (ParseException e) { 88 | params = new Object [] [] { 89 | {new Date(System.currentTimeMillis()), Integer.valueOf(1) } 90 | }; 91 | } 92 | 93 | return Arrays.asList(params); 94 | } 95 | @Test 96 | public void test() { 97 | 98 | ChartCycleData jsonChart = TableChartClient.callResource(targetDate); 99 | ChartInfoTable table = new ChartInfoTable(jsonChart); 100 | ChartInfoTableKey key = new ChartInfoTableKey(); 101 | key.setCityRegion(this.cityKey); 102 | key.setPeriodCode(this.editionKey); 103 | key.setChartType(this.typeKey); 104 | ChartCycleElementsJson element = table.get(key); 105 | assertEquals(this.expectedVersion, Integer.valueOf(Integer.parseInt(element.getChart_cycle_number()))); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/CycleDateTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import java.util.Calendar; 19 | import java.util.Date; 20 | import java.util.GregorianCalendar; 21 | import java.util.TimeZone; 22 | 23 | import org.junit.Test; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | import gov.faa.ait.apra.util.CycleDateUtil; 28 | 29 | public class CycleDateTest { 30 | private static final Logger logger = LoggerFactory.getLogger(CycleDateTest.class); 31 | 32 | @Test 33 | public void get56Day2CyclesAhead () { 34 | CycleDateUtil cdu = new CycleDateUtil(); 35 | Date d = cdu.get56DayCycleDate(2); 36 | logger.info("Next 56 day cycle date is "+cdu.getNext56Day().toString()); 37 | logger.info("Next after next 56 day cycle date is "+d.toString()); 38 | } 39 | 40 | @Test 41 | public void getBeforeCurrent56 () { 42 | CycleDateUtil cdu = new CycleDateUtil(); 43 | Date d = cdu.getPrevious56Day(); 44 | logger.info("Current 56 day cycle date is "+cdu.getCurrent56Day().toString()); 45 | logger.info("Cycle before current 56 day cycle date is "+d.toString()); 46 | } 47 | 48 | @Test 49 | public void get28Day2CyclesAhead () { 50 | CycleDateUtil cdu = new CycleDateUtil(); 51 | Date d = cdu.get28DayCycleDate(2); 52 | logger.info("Next 28 day cycle date is "+cdu.getNext28Day().toString()); 53 | logger.info("Next after next 28 day cycle date is "+d.toString()); 54 | } 55 | 56 | @Test 57 | public void getBeforeCurrent28 () { 58 | CycleDateUtil cdu = new CycleDateUtil(); 59 | Date d = cdu.getPrevious28Day(); 60 | logger.info("Current 28 day cycle date is "+cdu.getCurrent28Day().toString()); 61 | logger.info("Cycle before current 28 day cycle date is "+d.toString()); 62 | } 63 | 64 | @Test 65 | public void getDECCycle1 () { 66 | GregorianCalendar epoch = new GregorianCalendar(TimeZone.getDefault()); 67 | 68 | // Set the epoch to September 20, 2016 04:00:00 69 | epoch.set(2016, 8, 20, 4, 0, 0); 70 | int cycle = CycleDateUtil.getDECCycleNumber(epoch); 71 | 72 | logger.info("Calcualted cycle number "+cycle+" for date 09/20/2016"); 73 | assertEquals(cycle, 33); 74 | } 75 | 76 | @Test 77 | public void getDECCycle2 () { 78 | GregorianCalendar epoch = new GregorianCalendar(TimeZone.getDefault()); 79 | 80 | // Set the epoch to December 25, 2016 04:00:00 81 | epoch.set(2016, 11, 25, 4, 0, 0); 82 | int cycle = CycleDateUtil.getDECCycleNumber(epoch); 83 | 84 | logger.info("Calcualted cycle number "+cycle+" for date 12/25/2016"); 85 | 86 | assertEquals(cycle, 34); 87 | } 88 | 89 | @Test 90 | public void getDECCycle3 () { 91 | GregorianCalendar epoch = new GregorianCalendar(TimeZone.getDefault()); 92 | 93 | // Set the epoch to March 30, 2018 04:00:00 94 | epoch.set(2018, 2, 30, 4, 0, 0); 95 | int cycle = CycleDateUtil.getDECCycleNumber(epoch); 96 | logger.info("Calcualted cycle number "+cycle+" for date 03/30/2018"); 97 | 98 | assertEquals(cycle, 43); 99 | } 100 | 101 | @Test 102 | public void getDECCycle4 () { 103 | GregorianCalendar epoch = new GregorianCalendar(TimeZone.getDefault()); 104 | 105 | // Set the epoch to June 22, 2017 04:00:00 106 | epoch.set(2017, 5, 22, 4, 0, 0); 107 | int cycle = CycleDateUtil.getDECCycleNumber(epoch); 108 | logger.info("Calcualted cycle number "+cycle+" for date 06/22/2017"); 109 | 110 | assertEquals(cycle, 38); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/CIFPTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import java.util.Arrays; 19 | import java.util.Calendar; 20 | import java.util.Collection; 21 | import java.util.Date; 22 | import java.util.GregorianCalendar; 23 | 24 | import org.junit.Before; 25 | import org.junit.Test; 26 | import org.junit.runner.RunWith; 27 | import org.junit.runners.Parameterized; 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | 31 | import gov.faa.ait.apra.api.BaseService; 32 | import gov.faa.ait.apra.api.CIFP; 33 | import gov.faa.ait.apra.jaxb.ProductSet; 34 | import gov.faa.ait.apra.cycle.ChartCycleClient; 35 | import gov.faa.ait.apra.cycle.ChartCycleData; 36 | 37 | @RunWith(Parameterized.class) 38 | public class CIFPTest { 39 | private Date releaseDate = null; 40 | 41 | private final static Logger logger = LoggerFactory.getLogger(CIFPTest.class); 42 | private ChartCycleClient client; 43 | private CIFP cifp; 44 | 45 | public CIFPTest (Date date) { 46 | GregorianCalendar cal = new GregorianCalendar(); 47 | cal.clear(); 48 | cal.set(2015, 5, 1); 49 | this.releaseDate = cal.getTime(); 50 | } 51 | 52 | @Before 53 | public void initialize() { 54 | client = new ChartCycleClient(); 55 | cifp = new CIFP(); 56 | } 57 | 58 | @Parameterized.Parameters 59 | public static Collection cycleNumbers () { 60 | Date [] params = new Date [10]; 61 | 62 | GregorianCalendar cal = new GregorianCalendar(); 63 | cal.clear(); 64 | cal.set(2015, 0, 01); 65 | 66 | params[0] = cal.getTime(); 67 | for (int i = 1; i < 6; i++) { 68 | cal.add(Calendar.DATE, 56); 69 | params[i] = cal.getTime(); 70 | } 71 | 72 | cal.set(2016, 0, 7); 73 | params[6] = cal.getTime(); 74 | cal.set(2016, 1, 4); 75 | params[7] = cal.getTime(); 76 | cal.set (2016, 2, 3); 77 | params[8] = cal.getTime(); 78 | cal.set(2016, 2, 31); 79 | params[9] = cal.getTime(); 80 | 81 | 82 | return Arrays.asList(params); 83 | } 84 | 85 | @Test 86 | public void testDownloadOperations() { 87 | ChartCycleData cycle = client.getChartCycle(releaseDate, true); 88 | if (logger.isDebugEnabled()) { 89 | logger.debug("Reloaded cycle "+cycle.getName()); 90 | } 91 | 92 | cifp.setFormat(BaseService.ZIP); 93 | cifp.setEdition(BaseService.CURRENT); 94 | 95 | ProductSet current = cifp.getRelease(client.getCurrent28DayCycle()); 96 | 97 | if (current.getEdition().size() > 0) 98 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 99 | 100 | 101 | ProductSet next = cifp.getRelease(client.getNext28DayCycle()); 102 | if (next.getEdition().size() > 0) 103 | logger.info(next.getEdition().get(0).getProduct().getUrl()); 104 | } 105 | 106 | @Test 107 | public void testEditionOperations() { 108 | ChartCycleData cycle = client.getChartCycle(releaseDate, true); 109 | if (logger.isDebugEnabled()) { 110 | logger.debug("Reloaded cycle "+cycle.getName()); 111 | } 112 | 113 | cifp.setFormat(BaseService.ZIP); 114 | cifp.setEdition(BaseService.CURRENT); 115 | ProductSet current = cifp.getEdition(client.getCurrent28DayCycle()); 116 | assertEquals(new Integer(current.getStatus().getCode()), Integer.valueOf(200)); 117 | 118 | ProductSet next = cifp.getEdition(client.getNext28DayCycle()); 119 | assertEquals(new Integer(next.getStatus().getCode()), Integer.valueOf(200)); 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/WallPlanningChartsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.fail; 18 | 19 | import java.util.Arrays; 20 | import java.util.Calendar; 21 | import java.util.Collection; 22 | import java.util.Date; 23 | import java.util.GregorianCalendar; 24 | 25 | import org.junit.Before; 26 | import org.junit.Test; 27 | import org.junit.runner.RunWith; 28 | import org.junit.runners.Parameterized; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | 32 | import gov.faa.ait.apra.api.WallPlanningCharts; 33 | import gov.faa.ait.apra.jaxb.ProductSet; 34 | 35 | /** 36 | * WallPlanningChartsTest 37 | * @author FAA 38 | * 39 | */ 40 | 41 | @RunWith(Parameterized.class) 42 | public class WallPlanningChartsTest { 43 | private Date releaseDate = null; 44 | 45 | private static final Logger logger = LoggerFactory 46 | .getLogger(WallPlanningChartsTest.class); 47 | private WallPlanningCharts wallPlan; 48 | 49 | public WallPlanningChartsTest (Date date) { 50 | GregorianCalendar cal = new GregorianCalendar(); 51 | cal.clear(); 52 | cal.set(2015, 5, 1); 53 | this.releaseDate = cal.getTime(); 54 | } 55 | /** 56 | * initialize 57 | */ 58 | @Before 59 | public void initialize() { 60 | wallPlan = new WallPlanningCharts(); 61 | } 62 | /** 63 | * cycleNumbers 64 | * @return 65 | */ 66 | @Parameterized.Parameters 67 | public static Collection cycleNumbers() { 68 | Date[] params = new Date[10]; 69 | 70 | GregorianCalendar cal = new GregorianCalendar(); 71 | cal.clear(); 72 | cal.set(2015, 12, 11); 73 | 74 | params[0] = cal.getTime(); 75 | for (int i = 1; i < 6; i++) { 76 | cal.add(Calendar.DATE, 56); 77 | params[i] = cal.getTime(); 78 | } 79 | 80 | cal.set(2016, 0, 7); 81 | params[6] = cal.getTime(); 82 | cal.set(2016, 1, 4); 83 | params[7] = cal.getTime(); 84 | cal.set(2016, 2, 3); 85 | params[8] = cal.getTime(); 86 | cal.set(2016, 2, 31); 87 | params[9] = cal.getTime(); 88 | 89 | return Arrays.asList(params); 90 | } 91 | 92 | /** 93 | * testDownloadOperations 94 | */ 95 | @Test 96 | public void testDownloadOperations() { 97 | 98 | ProductSet current = (ProductSet) wallPlan.getProductRelease("current", "pdf").getEntity(); 99 | if (current.getEdition().size() > 0) 100 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 101 | assertEquals(Integer.valueOf(current.getStatus().getCode()), 102 | Integer.valueOf(200)); 103 | ProductSet next = (ProductSet) wallPlan.getProductRelease("next", "pdf").getEntity(); 104 | if (next.getEdition().size() > 0) 105 | logger.info(next.getEdition().get(0).getProduct().getUrl()); 106 | assertEquals(Integer.valueOf(next.getStatus().getCode()), Integer.valueOf(404)); 107 | } 108 | 109 | /** 110 | * testEditionOperations 111 | */ 112 | @Test 113 | public void testEditionOperations() { 114 | ProductSet current = (ProductSet) wallPlan.getProductEdition("current", "pdf").getEntity(); 115 | assertEquals(Integer.valueOf(current.getStatus().getCode()), 116 | Integer.valueOf(200)); 117 | 118 | ProductSet next = (ProductSet) wallPlan.getProductEdition("Next", "pdf").getEntity(); 119 | 120 | switch (next.getStatus().getCode()) { 121 | case 200: assertEquals(Integer.valueOf(200), Integer.valueOf(next.getStatus().getCode())); 122 | break; 123 | case 404: assertEquals(Integer.valueOf(404), Integer.valueOf(next.getStatus().getCode())); 124 | break; 125 | 126 | default: 127 | fail(); 128 | } 129 | 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/IFREnrouteChartsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import java.util.Arrays; 19 | import java.util.Calendar; 20 | import java.util.Collection; 21 | import java.util.Date; 22 | import java.util.GregorianCalendar; 23 | 24 | import org.junit.Before; 25 | import org.junit.Test; 26 | import org.junit.runner.RunWith; 27 | import org.junit.runners.Parameterized; 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | 31 | 32 | import gov.faa.ait.apra.api.IFREnrouteCharts; 33 | import gov.faa.ait.apra.jaxb.ProductSet; 34 | import gov.faa.ait.apra.cycle.ChartCycleClient; 35 | import gov.faa.ait.apra.cycle.ChartCycleData; 36 | 37 | /** 38 | * HelicopterChartsTest 39 | * @author Gangadhar CTR Gouri 40 | * 41 | */ 42 | 43 | @RunWith(Parameterized.class) 44 | public class IFREnrouteChartsTest { 45 | private Date releaseDate = null; 46 | private static boolean setupComplete = false; 47 | 48 | private static final Logger logger = LoggerFactory 49 | .getLogger(HelicopterChartsTest.class); 50 | private IFREnrouteCharts chats; 51 | 52 | public IFREnrouteChartsTest (Date date) { 53 | IFREnrouteChartsTest.setup(); 54 | GregorianCalendar cal = new GregorianCalendar(); 55 | cal.clear(); 56 | cal.set(2015, 5, 1); 57 | this.releaseDate = cal.getTime(); 58 | } 59 | 60 | private static void setup () { 61 | if (IFREnrouteChartsTest.setupComplete) { 62 | return; 63 | } 64 | ChartCycleClient client = new ChartCycleClient(); 65 | ChartCycleData cycle = client.getChartCycle(new Date (System.currentTimeMillis()), true); 66 | logger.info("Updated chart cycle in prep for IFR Enroute tests "+cycle.getName()); 67 | IFREnrouteChartsTest.setupComplete = true; 68 | } 69 | 70 | /** 71 | * initialize 72 | */ 73 | @Before 74 | public void initialize() { 75 | chats = new IFREnrouteCharts(); 76 | } 77 | /** 78 | * cycleNumbers 79 | * @return 80 | */ 81 | @Parameterized.Parameters 82 | public static Collection cycleNumbers() { 83 | Date[] params = new Date[10]; 84 | 85 | GregorianCalendar cal = new GregorianCalendar(); 86 | cal.clear(); 87 | cal.set(2015, 12, 11); 88 | 89 | params[0] = cal.getTime(); 90 | for (int i = 1; i < 6; i++) { 91 | cal.add(Calendar.DATE, 56); 92 | params[i] = cal.getTime(); 93 | } 94 | 95 | cal.set(2016, 0, 7); 96 | params[6] = cal.getTime(); 97 | cal.set(2016, 1, 4); 98 | params[7] = cal.getTime(); 99 | cal.set(2016, 2, 3); 100 | params[8] = cal.getTime(); 101 | cal.set(2016, 2, 31); 102 | params[9] = cal.getTime(); 103 | 104 | return Arrays.asList(params); 105 | } 106 | 107 | /** 108 | * testDownloadOperations 109 | */ 110 | @Test 111 | public void testDownloadOperations() { 112 | 113 | ProductSet current = (ProductSet) chats.getIFREnrouteRelease("current", "tiff", "US", "low").getEntity(); 114 | if (current.getEdition().size() > 0) 115 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 116 | assertEquals(Integer.valueOf(current.getStatus().getCode()), Integer.valueOf(200)); 117 | } 118 | 119 | /** 120 | * testEditionOperations 121 | */ 122 | @Test 123 | public void testEditionOperations() { 124 | 125 | ProductSet current = (ProductSet) chats.getIFREnrouteEdition("current").getEntity(); 126 | assertEquals(Integer.valueOf(current.getStatus().getCode()), Integer.valueOf( 127 | 200)); 128 | 129 | ProductSet next = (ProductSet) chats.getIFREnrouteEdition("Next").getEntity(); 130 | assertEquals(Integer.valueOf(next.getStatus().getCode()), Integer.valueOf(200)); 131 | 132 | 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/VFRChartsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.fail; 18 | import gov.faa.ait.apra.api.VFRCharts; 19 | import gov.faa.ait.apra.jaxb.ProductSet; 20 | 21 | 22 | import java.util.Arrays; 23 | import java.util.Calendar; 24 | import java.util.Collection; 25 | import java.util.Date; 26 | import java.util.GregorianCalendar; 27 | 28 | import org.junit.Before; 29 | import org.junit.Test; 30 | import org.junit.runner.RunWith; 31 | import org.junit.runners.Parameterized; 32 | import org.slf4j.Logger; 33 | import org.slf4j.LoggerFactory; 34 | 35 | @RunWith(Parameterized.class) 36 | public class VFRChartsTest { 37 | @SuppressWarnings("unused") 38 | private Date releaseDate = null; 39 | private static final Logger logger = LoggerFactory.getLogger(VFRChartsTest.class); 40 | private VFRCharts vfr; 41 | 42 | public VFRChartsTest (Date date) { 43 | GregorianCalendar cal = new GregorianCalendar(); 44 | cal.clear(); 45 | cal.set(2015, 5, 1); 46 | releaseDate = cal.getTime(); 47 | } 48 | /** 49 | * initialize 50 | */ 51 | @Before 52 | public void initialize() { 53 | vfr = new VFRCharts(); 54 | } 55 | /** 56 | * cycleNumbers 57 | * @return 58 | */ 59 | @Parameterized.Parameters 60 | public static Collection cycleNumbers() { 61 | Date[] params = new Date[10]; 62 | 63 | GregorianCalendar cal = new GregorianCalendar(); 64 | cal.clear(); 65 | cal.set(2015, 12, 11); 66 | 67 | params[0] = cal.getTime(); 68 | 69 | for (int i = 1; i < 6; i++) { 70 | cal.add(Calendar.DATE, 56); 71 | params[i] = cal.getTime(); 72 | } 73 | 74 | cal.set(2016, 0, 7); 75 | params[6] = cal.getTime(); 76 | cal.set(2016, 1, 4); 77 | params[7] = cal.getTime(); 78 | cal.set(2016, 2, 3); 79 | params[8] = cal.getTime(); 80 | cal.set(2016, 2, 31); 81 | params[9] = cal.getTime(); 82 | 83 | return Arrays.asList(params); 84 | } 85 | 86 | /** 87 | * testDownloadOperations 88 | */ 89 | @Test 90 | public void testDownloadOperations() { 91 | 92 | ProductSet current = (ProductSet) vfr.getGrandCanyonRelease("current").getEntity(); 93 | if (current.getEdition().size() > 0) 94 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 95 | assertEquals(Integer.valueOf(current.getStatus().getCode()), 96 | Integer.valueOf(200)); 97 | ProductSet next = (ProductSet) vfr.getGrandCanyonRelease("next").getEntity(); 98 | if (next.getEdition().size() > 0) 99 | logger.info(next.getEdition().get(0).getProduct().getUrl()); 100 | assertEquals(Integer.valueOf(next.getStatus().getCode()), Integer.valueOf(404)); 101 | } 102 | 103 | /** 104 | * testEditionOperations 105 | */ 106 | @Test 107 | public void testEditionOperations() { 108 | ProductSet current = (ProductSet) vfr.getGrandCanyonEdition("current").getEntity(); 109 | logger.info("Grand canyon edition current returned HTTP status code "+current.getStatus().getCode()); 110 | assertEquals(new Integer(200), new Integer(current.getStatus().getCode())); 111 | 112 | ProductSet next = (ProductSet) vfr.getGrandCanyonEdition("Next").getEntity(); 113 | logger.info("Grand canyon edition next returned HTTP status code "+current.getStatus().getCode()); 114 | 115 | int code = next.getStatus().getCode().intValue(); 116 | 117 | switch (code) { 118 | case 200: assertEquals(Integer.valueOf(200), Integer.valueOf(next.getStatus().getCode())); 119 | break; 120 | case 404: assertEquals(Integer.valueOf(404), Integer.valueOf(next.getStatus().getCode())); 121 | break; 122 | 123 | default: 124 | fail(); 125 | } 126 | 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/api/DigitalEnrouteSupplementCharts.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.api; 15 | 16 | 17 | import static gov.faa.ait.apra.bootstrap.ErrorCodes.DEPRECATED; 18 | 19 | import javax.ws.rs.GET; 20 | import javax.ws.rs.Path; 21 | import javax.ws.rs.Produces; 22 | import javax.ws.rs.QueryParam; 23 | import javax.ws.rs.core.MediaType; 24 | import javax.ws.rs.core.Response; 25 | 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import gov.faa.ait.apra.cycle.ChartCycleElementsJson; 30 | import gov.faa.ait.apra.jaxb.ProductSet; 31 | 32 | import io.swagger.annotations.Api; 33 | import io.swagger.annotations.ApiOperation; 34 | import io.swagger.annotations.ApiParam; 35 | import io.swagger.annotations.ApiResponse; 36 | import io.swagger.annotations.ApiResponses; 37 | 38 | 39 | @Path("/ders") 40 | @Api(value="Digital Enroute Supplement (DERS)") 41 | 42 | /** 43 | * As of June 2017, the DERS chart set has been discontinued. 44 | * This chart set is no longer available. 45 | * @author FAA 46 | * 47 | */ 48 | public class DigitalEnrouteSupplementCharts extends BaseService { 49 | 50 | private static final Logger logger = LoggerFactory.getLogger(DigitalEnrouteSupplementCharts.class); 51 | 52 | /** 53 | * This is the base chart download URL. A single parameter is provided to retrieve the URL for the current day's edition 54 | * @return 404 not found as this has been deprecated 55 | */ 56 | @GET 57 | @Deprecated 58 | @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) 59 | @Path("/chart") 60 | @ApiOperation(value="Get Digital Enroute Supplement download link.", 61 | notes="The Digital Enroute Supplement release is deprecated and publication has been discontinued as of June 2017.", 62 | response=ProductSet.class) 63 | @ApiResponses(value = {@ApiResponse(code = 404, message = DEPRECATED)}) 64 | 65 | public Response getDERSRelease ( 66 | @ApiParam(name="edition", value="Requested product edition. If omitted, current edition is returned.", allowableValues="current, next", defaultValue="current", allowMultiple=false, required=false) @QueryParam("edition") String ed) { 67 | 68 | logger.info("Received call to retrieve current DERS product release for edition."); 69 | ProductSet ps = buildResponse(null); 70 | return Response.status(ps.getStatus().getCode()).entity(ps).build(); 71 | } 72 | 73 | /** 74 | * This is the base chart download URL. A single parameter is provided to retrieve the URL for the current day's edition 75 | * @return 404 not found as this has been deprecated 76 | */ 77 | @GET 78 | @Deprecated 79 | @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) 80 | @Path("/info") 81 | @ApiOperation(value="Get Digital Enroute Supplement edition information.", 82 | notes="The Digital Enroute Supplement release is deprecated and publication has been discontinued as of June 2017.", 83 | response=ProductSet.class) 84 | @ApiResponses(value = {@ApiResponse(code = 404, message = DEPRECATED)}) 85 | 86 | public Response getDERSEdition ( 87 | @ApiParam(name="edition", value="Requested product edition. If omitted, current edition is returned.", allowableValues="current, next", defaultValue="current", allowMultiple=false, required=false) @QueryParam("edition") String ed) { 88 | 89 | ProductSet ps = buildResponse(null); 90 | return Response.status(ps.getStatus().getCode()).entity(ps).build(); 91 | } 92 | 93 | 94 | @Override 95 | protected ProductSet buildResponse(ChartCycleElementsJson cycle) { 96 | return initDeprecatedResponse(); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/util/GenericsUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.util; 15 | 16 | import java.lang.reflect.Array; 17 | import java.lang.reflect.GenericArrayType; 18 | import java.lang.reflect.ParameterizedType; 19 | import java.lang.reflect.Type; 20 | import java.lang.reflect.TypeVariable; 21 | import java.util.ArrayList; 22 | import java.util.HashMap; 23 | import java.util.List; 24 | import java.util.Map; 25 | /** 26 | * Class for getting generic type parameters. 27 | * 28 | * @author FAA 29 | * 30 | */ 31 | public class GenericsUtil { 32 | /** 33 | * Get the actual type arguments a child class has used to extend a generic 34 | * base class. (Taken from http://www.artima.com/weblogs/viewpost.jsp?thread=208860. Thanks 35 | * mathieu.grenonville for finding this solution!) 36 | * 37 | * @param baseClass 38 | * the base class 39 | * @param childClass 40 | * the child class 41 | * @return a list of the raw classes for the actual type arguments. 42 | */ 43 | public static List> getTypeArguments(Class baseClass, 44 | Class childClass) { 45 | Map resolvedTypes = new HashMap(); 46 | Type type = childClass; 47 | 48 | // start walking up the inheritance hierarchy until we hit baseClass 49 | while (!getClass(type).equals(baseClass)) { 50 | if (type instanceof Class) { 51 | // there is no useful information for us in raw types, so just 52 | // keep going. 53 | type = ((Class) type).getGenericSuperclass(); 54 | } else { 55 | ParameterizedType parameterizedType = (ParameterizedType) type; 56 | Class rawType = (Class) parameterizedType.getRawType(); 57 | 58 | Type[] actualTypeArguments = parameterizedType 59 | .getActualTypeArguments(); 60 | TypeVariable[] typeParameters = rawType.getTypeParameters(); 61 | for (int i = 0; i < actualTypeArguments.length; i++) { 62 | resolvedTypes 63 | .put(typeParameters[i], actualTypeArguments[i]); 64 | } 65 | 66 | if (!rawType.equals(baseClass)) { 67 | type = rawType.getGenericSuperclass(); 68 | } 69 | } 70 | } 71 | 72 | // finally, for each actual type argument provided to baseClass, 73 | // determine (if possible) 74 | // the raw class for that type argument. 75 | Type[] actualTypeArguments; 76 | if (type instanceof Class) { 77 | actualTypeArguments = ((Class) type).getTypeParameters(); 78 | } else { 79 | actualTypeArguments = ((ParameterizedType) type) 80 | .getActualTypeArguments(); 81 | } 82 | List> typeArgumentsAsClasses = new ArrayList>(); 83 | // resolve types by chasing down type variables. 84 | for (Type baseType : actualTypeArguments) { 85 | while (resolvedTypes.containsKey(baseType)) { 86 | baseType = resolvedTypes.get(baseType); 87 | } 88 | typeArgumentsAsClasses.add(getClass(baseType)); 89 | } 90 | return typeArgumentsAsClasses; 91 | } 92 | 93 | /** 94 | * Get the underlying class for a type, or null if the type is a variable 95 | * type. 96 | * 97 | * @param type 98 | * the type 99 | * @return the underlying class 100 | */ 101 | private static Class getClass(Type type) { 102 | if (type instanceof Class) { 103 | return (Class) type; 104 | } else if (type instanceof ParameterizedType) { 105 | return getClass(((ParameterizedType) type).getRawType()); 106 | } else if (type instanceof GenericArrayType) { 107 | Type componentType = ((GenericArrayType) type) 108 | .getGenericComponentType(); 109 | Class componentClass = getClass(componentType); 110 | if (componentClass != null) { 111 | return Array.newInstance(componentClass, 0).getClass(); 112 | } else { 113 | return null; 114 | } 115 | } else { 116 | return null; 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/util/ChartInfoTableKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.util; 15 | 16 | import org.slf4j.Logger; 17 | import org.slf4j.LoggerFactory; 18 | 19 | public class ChartInfoTableKey { 20 | private static final Logger logger = LoggerFactory.getLogger(ChartInfoTableKey.class); 21 | private String cityRegion; 22 | private String periodCode; 23 | private String chartType; 24 | 25 | /** 26 | * Default constructor nulls fields 27 | */ 28 | public ChartInfoTableKey() { 29 | cityRegion=null; 30 | periodCode=null; 31 | chartType=null; 32 | } 33 | 34 | /** 35 | * Property value constructor 36 | * @param cityRegion the geo area to use 37 | * @param periodCode current or next 38 | * @param chartType type of chart 39 | */ 40 | public ChartInfoTableKey(String cityRegion, String periodCode, String chartType) { 41 | 42 | if (logger.isDebugEnabled()) 43 | logger.debug("Creating Key("+cityRegion+","+periodCode+","+chartType+")"); 44 | 45 | this.cityRegion = cityRegion; 46 | this.periodCode = periodCode; 47 | this.chartType = chartType; 48 | } 49 | 50 | /** 51 | * return the chartType 52 | * @return 53 | */ 54 | public String getChartType() { 55 | return this.chartType; 56 | } 57 | /** 58 | * @param chartType the chartType to set 59 | */ 60 | public void setChartType(String chartType) { 61 | this.chartType = chartType; 62 | } 63 | 64 | /** 65 | * @return the cityRegion 66 | */ 67 | public String getCityRegion() { 68 | return cityRegion; 69 | } 70 | /** 71 | * @param cityRegion the cityRegion to set 72 | */ 73 | public void setCityRegion(String cityRegion) { 74 | this.cityRegion = cityRegion; 75 | } 76 | /** 77 | * @return the periodCode 78 | */ 79 | public String getPeriodCode() { 80 | return periodCode; 81 | } 82 | /** 83 | * @param periodCode the periodCode to set 84 | */ 85 | public void setPeriodCode(String periodCode) { 86 | 87 | this.periodCode = periodCode; 88 | } 89 | 90 | /** 91 | * override the toString method for debugging and logging 92 | */ 93 | @Override 94 | public String toString() { 95 | StringBuilder sb = new StringBuilder(); 96 | sb.append("Key-") 97 | .append(this.cityRegion).append("::").append(this.periodCode) 98 | .append("::").append(this.chartType); 99 | return sb.toString(); 100 | 101 | } 102 | 103 | /* (non-Javadoc) 104 | * @see java.lang.Object#hashCode() 105 | */ 106 | @Override 107 | public int hashCode() { 108 | final int prime = 31; 109 | int result = 1; 110 | result = prime * result + ((chartType == null) ? 0 : chartType.hashCode()); 111 | result = prime * result + ((cityRegion == null) ? 0 : cityRegion.hashCode()); 112 | result = prime * result + ((periodCode == null) ? 0 : periodCode.hashCode()); 113 | return result; 114 | } 115 | 116 | /* (non-Javadoc) 117 | * @see java.lang.Object#equals(java.lang.Object) 118 | */ 119 | @Override 120 | public boolean equals(Object obj) { 121 | if (this == obj) { 122 | return true; 123 | } 124 | if (obj == null) { 125 | return false; 126 | } 127 | 128 | /* 129 | if (!(obj instanceof ChartInfoTableKey)) { 130 | return false; 131 | } 132 | */ 133 | 134 | if (this.getClass() != obj.getClass()) { 135 | return false; 136 | } 137 | 138 | ChartInfoTableKey other = (ChartInfoTableKey) obj; 139 | if (chartType == null) { 140 | if (other.chartType != null) { 141 | return false; 142 | } 143 | } else if (!chartType.equals(other.chartType)) { 144 | return false; 145 | } 146 | if (cityRegion == null) { 147 | if (other.cityRegion != null) { 148 | return false; 149 | } 150 | } else if (!cityRegion.equals(other.cityRegion)) { 151 | return false; 152 | } 153 | if (periodCode == null) { 154 | if (other.periodCode != null) { 155 | return false; 156 | } 157 | } else if (!periodCode.equals(other.periodCode)) { 158 | return false; 159 | } 160 | return true; 161 | } 162 | 163 | } -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/CityNameConversionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import org.junit.Test; 17 | import org.slf4j.Logger; 18 | import org.slf4j.LoggerFactory; 19 | 20 | import gov.faa.ait.apra.api.TerminalAreaCharts; 21 | 22 | public class CityNameConversionTest { 23 | private final static Logger logger = LoggerFactory.getLogger(CityNameConversionTest.class); 24 | 25 | @Test 26 | public void convertPR () { 27 | TerminalAreaCharts tac = new TerminalAreaCharts(); 28 | tac.setCity("puerto Rico-IV"); 29 | logger.info("puerto Rico-IV converted to "+tac.getCity()); 30 | } 31 | 32 | @Test 33 | public void convertTampa () { 34 | TerminalAreaCharts tac = new TerminalAreaCharts(); 35 | tac.setCity("tampa-orlando"); 36 | logger.info("tampa-orlando converted to "+tac.getCity()); 37 | } 38 | 39 | 40 | @Test 41 | public void convertDallas () { 42 | TerminalAreaCharts tac = new TerminalAreaCharts(); 43 | tac.setCity("dallas-ft worth"); 44 | logger.info("dallas-ft worth converted to "+tac.getCity()); 45 | } 46 | 47 | 48 | @Test 49 | public void convertMSP () { 50 | TerminalAreaCharts tac = new TerminalAreaCharts(); 51 | tac.setCity("Minneapolis-St Paul"); 52 | logger.info("Minneapolis-St Paul converted to "+tac.getCity()); 53 | } 54 | 55 | @Test 56 | public void convertMSPlower () { 57 | TerminalAreaCharts tac = new TerminalAreaCharts(); 58 | tac.setCity("minneapolis-st paul"); 59 | logger.info("minneapolis-st paul converted to "+tac.getCity()); 60 | } 61 | 62 | @Test 63 | public void convertDEN () { 64 | TerminalAreaCharts tac = new TerminalAreaCharts(); 65 | tac.setCity("Denver-Colorado Springs"); 66 | logger.info("Denver-Colorado Springs converted to "+tac.getCity()); 67 | } 68 | 69 | @Test 70 | public void convertDENmixed () { 71 | TerminalAreaCharts tac = new TerminalAreaCharts(); 72 | tac.setCity("denver-Colorado springs"); 73 | logger.info("denver-Colorado springs converted to "+tac.getCity()); 74 | } 75 | 76 | @Test 77 | public void formatPR () { 78 | TerminalAreaCharts tac = new TerminalAreaCharts(); 79 | tac.setCity("puerto Rico-IV"); 80 | String val = tac.formatCity(); 81 | logger.info("puerto Rico-IV formatted as "+val); 82 | } 83 | 84 | @Test 85 | public void formatPRlower () { 86 | TerminalAreaCharts tac = new TerminalAreaCharts(); 87 | tac.setCity("puerto rico-iv"); 88 | String val = tac.formatCity(); 89 | logger.info("puerto rico-iv formatted as "+val); 90 | } 91 | 92 | @Test 93 | public void formatTampa () { 94 | TerminalAreaCharts tac = new TerminalAreaCharts(); 95 | tac.setCity("tampa-orlando"); 96 | String val = tac.formatCity(); 97 | logger.info("tampa-orlando formatted as "+val); 98 | } 99 | 100 | 101 | @Test 102 | public void formatDallas () { 103 | TerminalAreaCharts tac = new TerminalAreaCharts(); 104 | tac.setCity("dallas-ft worth"); 105 | String val = tac.formatCity(); 106 | logger.info("dallas-ft worth formatted as "+val); 107 | } 108 | 109 | 110 | @Test 111 | public void formatMSP () { 112 | TerminalAreaCharts tac = new TerminalAreaCharts(); 113 | tac.setCity("Minneapolis-St Paul"); 114 | String val = tac.formatCity(); 115 | logger.info("Minneapolis-St Paul formatted as "+val); 116 | } 117 | 118 | @Test 119 | public void formatMSPlower () { 120 | TerminalAreaCharts tac = new TerminalAreaCharts(); 121 | tac.setCity("minneapolis-st paul"); 122 | String val = tac.formatCity(); 123 | logger.info("minneapolis-st paul formatted as "+val); 124 | } 125 | 126 | @Test 127 | public void formatDEN () { 128 | TerminalAreaCharts tac = new TerminalAreaCharts(); 129 | tac.setCity("Denver-Colorado Springs"); 130 | String val = tac.formatCity(); 131 | logger.info("Denver-Colorado Springs converted to "+val); 132 | } 133 | 134 | @Test 135 | public void formatDENmixed () { 136 | TerminalAreaCharts tac = new TerminalAreaCharts(); 137 | tac.setCity("denver-Colorado springs"); 138 | String val = tac.formatCity(); 139 | logger.info("denver-Colorado springs converted to "+val); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/util/TableChartClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.util; 15 | 16 | import java.text.SimpleDateFormat; 17 | import java.util.Date; 18 | import java.util.concurrent.TimeUnit; 19 | 20 | import javax.ws.rs.client.Client; 21 | import javax.ws.rs.client.ClientBuilder; 22 | import javax.ws.rs.client.WebTarget; 23 | import javax.ws.rs.core.MediaType; 24 | 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | import gov.faa.ait.apra.bootstrap.Config; 29 | import gov.faa.ait.apra.cycle.ChartCycleData; 30 | 31 | public class TableChartClient { 32 | 33 | private static Logger logger = LoggerFactory.getLogger(TableChartClient.class); 34 | private static ChartInfoTable sectionalTable; 35 | private static Date lastUpdate; 36 | private Date today; 37 | 38 | /** 39 | * Default constructor 40 | * Initializes today to current time 41 | */ 42 | public TableChartClient() { 43 | this.today = new Date(System.currentTimeMillis()); 44 | if(updateRequired()) { 45 | updateTable(); 46 | } 47 | } 48 | 49 | /** 50 | * Initializes client with a specified date 51 | * @param date date used for query date 52 | */ 53 | public TableChartClient(Date date) { 54 | this.today = new Date (date.getTime()); 55 | } 56 | 57 | private static void updateTable() { 58 | // initiate call to REST 59 | TableChartClient.lastUpdate = new Date(System.currentTimeMillis()); 60 | ChartCycleData chartJson = callResource(TableChartClient.lastUpdate); 61 | if(chartJson!=null) { 62 | TableChartClient.sectionalTable = new ChartInfoTable(chartJson); 63 | } 64 | } 65 | 66 | public static ChartCycleData callResource(Date targetDate) { 67 | /* example: 68 | * https://soadev.sm.faa.gov/denodo/apra/server/ifpa/edai/views/vfr_chart_cycle?query_date=6/15/2016&%24format=json 69 | */ 70 | String unbound = ""; 71 | 72 | SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); 73 | StringBuilder url = new StringBuilder(); 74 | url.append(Config.getDenodoHost()).append(Config.getDenodoVFRCycleResource()).append("?query_date=") 75 | .append(sdf.format(targetDate)) 76 | .append("&%24format=json"); 77 | logger.info("Calling denodo for sectional at "+url.toString()); 78 | TableChartClient.lastUpdate = new Date(System.currentTimeMillis()); 79 | 80 | try { 81 | Client client = ClientBuilder.newClient(); 82 | 83 | WebTarget webTarget = client.target(url.toString()); 84 | 85 | long now = System.currentTimeMillis(); 86 | unbound = webTarget.request(MediaType.APPLICATION_JSON_TYPE).get(String.class); 87 | long duration = System.currentTimeMillis() - now; 88 | logger.info("Call for sectional chart cycle took "+duration+" ms"); 89 | 90 | if (logger.isDebugEnabled()) 91 | logger.debug("JSON return value for sectional chart cycle = "+unbound); 92 | 93 | ChartCycleJsonUnmarshaller converter = new ChartCycleJsonUnmarshaller(); 94 | logger.debug("Got the unmarshaller ChartCycleJsonUnmarshaller"); 95 | ChartCycleData sectionJson = converter.unmarshalJson(unbound); 96 | logger.debug("Got the converter for ChartCycleData and unmarshalled the unbound string. Returning sectionJson"); 97 | return sectionJson; 98 | } 99 | catch (Exception ex) { 100 | logger.error("Error calling service",ex); 101 | TableChartClient.sectionalTable = null; 102 | return null; 103 | } 104 | 105 | } 106 | 107 | 108 | private boolean updateRequired() { 109 | boolean update; 110 | if(TableChartClient.lastUpdate == null || TableChartClient.sectionalTable == null ) { 111 | update = true; 112 | } else { 113 | long diff = this.today.getTime() - TableChartClient.lastUpdate.getTime(); 114 | long hours = TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS); 115 | 116 | update = (hours >= Config.getCycleAgeLimit()); 117 | } 118 | return update; 119 | } 120 | 121 | public static ChartInfoTable getTable(TableChartClient client) { 122 | if(client.updateRequired()) { 123 | TableChartClient.updateTable(); 124 | } 125 | return TableChartClient.sectionalTable; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/bootstrap/USStateReferenceData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.bootstrap; 15 | 16 | import java.text.SimpleDateFormat; 17 | import java.util.HashMap; 18 | import java.util.Locale; 19 | 20 | import javax.ws.rs.client.Client; 21 | import javax.ws.rs.client.ClientBuilder; 22 | import javax.ws.rs.client.WebTarget; 23 | import javax.ws.rs.core.MediaType; 24 | 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | import com.fasterxml.jackson.databind.DeserializationFeature; 29 | import com.fasterxml.jackson.databind.ObjectMapper; 30 | import com.google.common.base.Charsets; 31 | 32 | import gov.faa.ait.apra.json.USState; 33 | import gov.faa.ait.apra.json.USStateReference; 34 | 35 | /** 36 | * The state reference data is loaded from an external REST service. 37 | * The service provides state names and abbreviations. 38 | * @author FAA 39 | * 40 | */ 41 | public class USStateReferenceData { 42 | private static final Logger logger = LoggerFactory.getLogger(USStateReferenceData.class); 43 | private static HashMap stateByName = new HashMap <> (); 44 | private static HashMap stateByAbbreviation = new HashMap <> (); 45 | 46 | private USStateReferenceData() { } 47 | 48 | static { 49 | USStateReferenceData.loadStateData(); 50 | } 51 | 52 | /** 53 | * Load the state reference data from Denodo. 54 | */ 55 | private static void loadStateData () { 56 | logger.info("Starting load of US state reference data from denodo"); 57 | try { 58 | StringBuilder url = new StringBuilder(); 59 | url = url.append(Config.getDenodoHost()).append(Config.getDenodoViewPath()).append("/state_reference?%24format=json"); 60 | 61 | Client client = ClientBuilder.newClient(); 62 | 63 | WebTarget webTarget = client.target(url.toString()); 64 | long now = System.currentTimeMillis(); 65 | String unbound = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(String.class); 66 | long duration = System.currentTimeMillis() - now; 67 | logger.info("Call US state reference data took "+duration+" ms"); 68 | ObjectMapper mapper = new ObjectMapper(); 69 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 70 | mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); 71 | USStateReference data = mapper.readValue(unbound.getBytes(Charsets.UTF_16), USStateReference.class); 72 | USState [] states = data.getElements(); 73 | 74 | for (int i = 0; i < states.length; i++) { 75 | stateByAbbreviation.put(states[i].getAbbreviation().toUpperCase(), states[i].getName().toUpperCase()); 76 | stateByName.put(states[i].getName().toUpperCase(), states[i].getAbbreviation().toUpperCase()); 77 | } 78 | } 79 | catch (Exception ex) { 80 | logger.warn("Unable to load the US state reference data from denodo", ex); 81 | } 82 | } 83 | 84 | /** 85 | * Get the state abbreviation given a full state name 86 | * @param stateName the full name of the state for which an abbreviation is required 87 | * @return 88 | */ 89 | public static String getAbbreviation (String stateName) { 90 | return stateByName.get(stateName); 91 | } 92 | 93 | /** 94 | * Get the state name given a 2-letter state abbreviation 95 | * @param abbreviation the 2-letter abbreviation for which a state name is required 96 | * @return 97 | */ 98 | public static String getStateName (String abbreviation) { 99 | return stateByAbbreviation.get(abbreviation); 100 | } 101 | 102 | /** 103 | * Check to see if a state exists in the reference data 104 | * @param stateName the name of the state to check 105 | * @return true if the state exists in the reference data set; false otherwise 106 | */ 107 | public static boolean stateNameExists (String stateName) { 108 | return stateByName.containsKey(stateName.toUpperCase(Locale.ENGLISH)); 109 | } 110 | 111 | /** 112 | * Check to see if a state exists in the reference data using the state abbreviation 113 | * @param abbr the 2-letter abbreviation of the state to check 114 | * @return true if the state exists in the reference data set; false otherwise 115 | */ 116 | public static boolean stateAbbreviationExists (String abbr) { 117 | return stateByAbbreviation.containsKey(abbr.toUpperCase(Locale.ENGLISH)); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/util/SupplementMetadataClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.util; 15 | 16 | import java.io.UnsupportedEncodingException; 17 | 18 | import java.text.SimpleDateFormat; 19 | 20 | import javax.ws.rs.client.Client; 21 | import javax.ws.rs.client.ClientBuilder; 22 | import javax.ws.rs.client.WebTarget; 23 | import javax.ws.rs.core.MediaType; 24 | 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | import com.fasterxml.jackson.databind.DeserializationFeature; 29 | import com.fasterxml.jackson.databind.ObjectMapper; 30 | 31 | import gov.faa.ait.apra.bootstrap.Config; 32 | import gov.faa.ait.apra.cycle.ChartCycleElementsJson; 33 | import gov.faa.ait.apra.json.SupplementChartMetadata; 34 | 35 | /** 36 | * This is the class that retrieves all of the Supplement metadata from the virtualized XML file in denodo. 37 | * 38 | */ 39 | public class SupplementMetadataClient { 40 | private StringBuilder url; 41 | private String edition; 42 | private static final Logger logger = LoggerFactory.getLogger(SupplementMetadataClient.class); 43 | private static final String BASE_URI=Config.getDenodoHost()+Config.getDenodoViewPath()+"/afd_chart_metadata?"; 44 | private static final String CHART_DATE="chart_date="; 45 | private static final String VOLUME_PARAM="&volume_name="; 46 | private static final String JSON_FORMAT="&%24format=json"; 47 | 48 | /** 49 | * Setup the base URI for the denodo endpoint and add parameters for edition. 50 | * @param cycle the current or next 56 day cycle used for Supplement charts 51 | */ 52 | public SupplementMetadataClient (ChartCycleElementsJson cycle) { 53 | this.url = new StringBuilder(BASE_URI); 54 | 55 | logger.info("Chart effective date "+cycle.getChart_effective_date()); 56 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); 57 | this.url = this.url.append(CHART_DATE).append(formatter.format(cycle.getChart_effective_date())); 58 | 59 | logger.info("URL for Supplement metadata query constructed as is currently "+url); 60 | } 61 | 62 | /** 63 | * Get the Supplement chart metadata for all charts. No additional query parameters for state or volume are added 64 | * @return 65 | */ 66 | public SupplementChartMetadata getSupplementChartMetadata () { 67 | this.url.append(JSON_FORMAT); 68 | return getSupplementChartMetadataQuery (); 69 | } 70 | 71 | 72 | /** 73 | * Get the Supplement metadata for a specific volume 74 | * @param volumeName the name of the volume for which metadata is requsted such as NE-1 75 | * @return 76 | */ 77 | public SupplementChartMetadata getChartMetadataByVolume (String vol) { 78 | String volumeName; 79 | 80 | if (vol == null) { 81 | volumeName = ""; 82 | } 83 | else { 84 | volumeName = vol; 85 | } 86 | 87 | try { 88 | volumeName = java.net.URLEncoder.encode(volumeName, "UTF-8").replace("+","%20"); 89 | } catch (UnsupportedEncodingException e) { 90 | logger.error(" volumeName encode issue ", e); 91 | } 92 | 93 | this.url = this.url.append(VOLUME_PARAM).append(volumeName).append(JSON_FORMAT); 94 | return getSupplementChartMetadataQuery (); 95 | } 96 | 97 | // This is the meat of the operation. Once we have the query string all setup based upon the calls for state, volume or others, we execute the request against denodo 98 | private SupplementChartMetadata getSupplementChartMetadataQuery () { 99 | String unbound = ""; 100 | 101 | try { 102 | logger.info("Calling denodo for Supplement metadata at "+url.toString()); 103 | 104 | Client client = ClientBuilder.newClient(); 105 | WebTarget webTarget = client.target(this.url.toString()); 106 | 107 | long now = System.currentTimeMillis(); 108 | unbound = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(String.class); 109 | long duration = System.currentTimeMillis() - now; 110 | logger.info("Call for Supplement Metadata took "+duration+" ms"); 111 | ObjectMapper mapper = new ObjectMapper(); 112 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 113 | mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); 114 | return mapper.readValue(unbound.getBytes("UTF-8"), SupplementChartMetadata.class); 115 | } 116 | catch (Exception ex) { 117 | logger.warn("Error getting chart cycle information using url "+this.url.toString(), ex); 118 | return null; 119 | } 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/HelicopterChartsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | 19 | import java.util.Arrays; 20 | import java.util.Calendar; 21 | import java.util.Collection; 22 | import java.util.Date; 23 | import java.util.GregorianCalendar; 24 | 25 | import org.junit.Before; 26 | import org.junit.Test; 27 | import org.junit.runner.RunWith; 28 | import org.junit.runners.Parameterized; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | 32 | import gov.faa.ait.apra.api.HelicopterCharts; 33 | import gov.faa.ait.apra.jaxb.ProductSet; 34 | 35 | /** 36 | * HelicopterChartsTest 37 | * 38 | * @author Gangadhar CTR Gouri 39 | * 40 | */ 41 | 42 | @RunWith(Parameterized.class) 43 | public class HelicopterChartsTest { 44 | private Date releaseDate = null; 45 | 46 | private static final Logger logger = LoggerFactory 47 | .getLogger(HelicopterChartsTest.class); 48 | private HelicopterCharts helicopter; 49 | 50 | public HelicopterChartsTest(Date date) { 51 | GregorianCalendar cal = new GregorianCalendar(); 52 | cal.clear(); 53 | cal.set(2015, 5, 1); 54 | this.releaseDate = cal.getTime(); 55 | } 56 | 57 | /** 58 | * initialize 59 | */ 60 | @Before 61 | public void initialize() { 62 | helicopter = new HelicopterCharts(); 63 | } 64 | 65 | /** 66 | * cycleNumbers 67 | * 68 | * @return 69 | */ 70 | @Parameterized.Parameters 71 | public static Collection cycleNumbers() { 72 | Date[] params = new Date[10]; 73 | 74 | GregorianCalendar cal = new GregorianCalendar(); 75 | cal.clear(); 76 | cal.set(2015, 12, 11); 77 | 78 | params[0] = cal.getTime(); 79 | 80 | for (int i = 1; i < 6; i++) { 81 | cal.add(Calendar.DATE, 56); 82 | params[i] = cal.getTime(); 83 | } 84 | 85 | cal.set(2016, 0, 7); 86 | params[6] = cal.getTime(); 87 | cal.set(2016, 1, 4); 88 | params[7] = cal.getTime(); 89 | cal.set(2016, 2, 3); 90 | params[8] = cal.getTime(); 91 | cal.set(2016, 2, 31); 92 | params[9] = cal.getTime(); 93 | 94 | return Arrays.asList(params); 95 | } 96 | 97 | /** 98 | * testDownloadOperations 99 | */ 100 | @Test 101 | public void testDownloadOperations() { 102 | 103 | ProductSet ps = (ProductSet) helicopter.getHelicopterRelease("current", "PDF", "Houston Heli").getEntity(); 104 | if (ps.getEdition().size() > 0) 105 | logger.info(ps.getEdition().get(0).getProduct().getUrl()); 106 | int code = ps.getStatus().getCode().intValue(); 107 | if (code == 200) { 108 | if ((ps.getEdition().get(0).getEditionDate() != null) 109 | && (!ps.getEdition().get(0).getEditionDate().isEmpty())) { 110 | logger.info("Helicopter Product Relese Test for 'current' return url of " 111 | + ps.getEdition().get(0).getProduct().getUrl()); 112 | if (ps.getEdition().get(0).getProduct().getUrl() != null) { 113 | 114 | assertTrue(VerifyValues.verifyURL(ps.getEdition().get(0) 115 | .getProduct().getUrl())); 116 | } 117 | } 118 | } else { 119 | assertEquals(code, 404); 120 | } 121 | 122 | ps = (ProductSet) helicopter.getHelicopterRelease("next", "PDF", "Houston Heli").getEntity(); 123 | code = ps.getStatus().getCode().intValue(); 124 | 125 | if (code == 200) { 126 | logger.info("Status code is "+code); 127 | if ((ps.getEdition().get(0).getEditionDate() != null) 128 | && (!ps.getEdition().get(0).getEditionDate().isEmpty())) { 129 | logger.info("Helicopter Product Relese Test for 'Next' return url of " 130 | + ps.getEdition().get(0).getProduct().getUrl()); 131 | 132 | if (ps.getEdition().get(0).getProduct().getUrl() != null) { 133 | assertTrue(VerifyValues.verifyURL(ps.getEdition().get(0) 134 | .getProduct().getUrl())); 135 | } 136 | } 137 | } else { 138 | assertEquals(code, 404); 139 | } 140 | 141 | } 142 | 143 | /** 144 | * testEditionOperations 145 | */ 146 | @Test 147 | public void testEditionOperations() { 148 | 149 | ProductSet ps = (ProductSet) helicopter.getHelicopterEdition("current", "Houston Heli").getEntity(); 150 | int code = ps.getStatus().getCode().intValue(); 151 | 152 | if (code == 200) { 153 | assertEquals(code, 200); 154 | } else { 155 | assertEquals(code, 404); 156 | } 157 | 158 | ps = (ProductSet) helicopter.getHelicopterEdition("Next", "Houston Heli").getEntity(); 159 | code = ps.getStatus().getCode().intValue(); 160 | 161 | if (code == 200) { 162 | assertEquals(code, 200); 163 | } else { 164 | assertEquals(code, 404); 165 | } 166 | 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | 6 | gov.faa.ait 7 | apra 8 | war 9 | 1.2.${revision} 10 | apra 11 | 12 | 13 | 14 | 15 | false 16 | 17 | central 18 | libs-release 19 | http://artifactory.faa.gov:8081/artifactory/libs-release 20 | 21 | 22 | 23 | snapshots 24 | libs-snapshot 25 | http://artifactory.faa.gov:8081/artifactory/libs-snapshot 26 | 27 | 28 | 29 | faa-apra 30 | faa-apra 31 | http://artifactory.faa.gov:8081/artifactory/faa-apra 32 | 33 | 34 | 35 | 36 | 37 | apra 38 | 39 | 40 | org.apache.maven.plugins 41 | maven-compiler-plugin 42 | 2.5.1 43 | true 44 | 45 | 1.8 46 | 1.8 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | org.glassfish.jersey 56 | jersey-bom 57 | ${jersey.version} 58 | pom 59 | import 60 | 61 | 62 | org.glassfish.jersey.containers 63 | jersey-container-servlet 64 | 2.25.1 65 | 66 | 67 | 68 | 69 | 70 | 71 | org.glassfish.jersey.media 72 | jersey-media-moxy 73 | 74 | 75 | log4j 76 | log4j 77 | 1.2.12 78 | 79 | 80 | org.apache.logging.log4j 81 | log4j-core 82 | 2.17.1 83 | 84 | 85 | org.apache.logging.log4j 86 | log4j-slf4j-impl 87 | 2.4.1 88 | 89 | 90 | junit 91 | junit 92 | 4.12 93 | 94 | 95 | com.fasterxml.jackson.core 96 | jackson-databind 97 | 2.15.2 98 | 99 | 100 | com.fasterxml.jackson.core 101 | jackson-core 102 | 2.15.2 103 | 104 | 105 | io.swagger 106 | swagger-jersey2-jaxrs 107 | 1.5.0 108 | 109 | 110 | org.apache.logging.log4j 111 | log4j-web 112 | 2.4.1 113 | 114 | 115 | gov.faa.ait 116 | apraresponse 117 | [1.0,2.0) 118 | 119 | 120 | org.glassfish.jersey.containers 121 | jersey-container-servlet 122 | 123 | 124 | org.glassfish.jersey.core 125 | jersey-client 126 | 2.25.1 127 | 128 | 129 | javax.ws.rs 130 | javax.ws.rs-api 131 | 2.0.1 132 | 133 | 134 | 135 | 2.25.1 136 | UTF-8 137 | 0 138 | 139 | 140 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/cycle/DenodoClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.cycle; 15 | 16 | import java.text.SimpleDateFormat; 17 | import java.util.Date; 18 | 19 | import javax.ws.rs.client.Client; 20 | import javax.ws.rs.client.ClientBuilder; 21 | import javax.ws.rs.client.WebTarget; 22 | import javax.ws.rs.core.MediaType; 23 | 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | import com.fasterxml.jackson.databind.DeserializationFeature; 28 | import com.fasterxml.jackson.databind.ObjectMapper; 29 | import com.google.common.base.Charsets; 30 | 31 | /** 32 | * Here we are getting the 28 or 56 day chart cycle from the APRA support services. This is a regular chart cycle publication and the dates 33 | * plus edition numbers are maintained outside of APRA. Data sources for this information are managed by the FAA chart production team and processes. 34 | * This client is a convenience class to pull the cycle edition dates and numbers from an external source. 35 | * @author FAA 36 | * 37 | */ 38 | public abstract class DenodoClient { 39 | private Date today; 40 | private ChartCycleData cycle = null; 41 | private static final Logger logger = LoggerFactory.getLogger(ChartCycleClient.class); 42 | 43 | /** 44 | * Construct the default chart cycle client to obtain the 28 day or 56 day chart cycle from denodo 45 | */ 46 | public DenodoClient () { 47 | this.today = new Date (System.currentTimeMillis()); 48 | } 49 | 50 | /** 51 | * Force an update of the chart cycle by reaching back to denodo and retrieving an update. 52 | * The update is based on the current system date 53 | * @return the updated ChartCycleData from denodo 54 | */ 55 | public ChartCycleData forceUpdate () { 56 | return getChartCycle(today, true); 57 | } 58 | 59 | /** 60 | * Get a chart cycle using todays date and specify whether to force an update by 61 | * retrieving the latest cycle from the denodo data source 62 | * @param forceUpdate boolean to specify whether the cache should be updated 63 | * @return the Json representation of the chart cycle 64 | */ 65 | public ChartCycleData getChartCycle (boolean forceUpdate) { 66 | return getChartCycle (today, forceUpdate); 67 | } 68 | 69 | /** 70 | * The base method to retrieve a chart cycle given a specific date and specify whether to force 71 | * an update of the cache 72 | * @param targetDate the date for which the chart cycle is required 73 | * @param forceUpdate specify whether to force an update of the chart cycle cache 74 | * @return the chart cycle in Json format bound to the Json POJO 75 | */ 76 | public ChartCycleData getChartCycle (Date targetDate, boolean forceUpdate) { 77 | String url; 78 | 79 | if (! forceUpdate) { 80 | return getChartCycle(); 81 | } 82 | 83 | url = getWebTarget(targetDate); 84 | 85 | logger.info("Calling denodo for chart cycle at "+url); 86 | 87 | setLastUpdate(); 88 | 89 | String unbound = ""; 90 | 91 | try { 92 | Client client = ClientBuilder.newClient(); 93 | 94 | WebTarget webTarget = client.target(url); 95 | long now = System.currentTimeMillis(); 96 | unbound = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(String.class); 97 | long duration = System.currentTimeMillis() - now; 98 | logger.info("Call for 28/56 day chart cycle took "+duration+" ms"); 99 | ObjectMapper mapper = new ObjectMapper(); 100 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 101 | mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); 102 | setChartCycle (mapper.readValue(unbound.getBytes(Charsets.UTF_16), ChartCycleData.class)); 103 | } 104 | catch (Exception ex) { 105 | logger.warn("Error getting chart cycle information.", ex); 106 | setChartCycle(null); 107 | return null; 108 | } 109 | return cycle; 110 | } 111 | 112 | /** 113 | * Retrieve the chart cycle using today's date and do not force a refresh 114 | * @return 115 | */ 116 | public abstract ChartCycleData getChartCycle(); 117 | 118 | /** 119 | * Get the date that this client was last updated for cache aging purposes 120 | * @return the date of the last update 121 | */ 122 | public abstract Date getLastUpdate(); 123 | 124 | protected abstract void setLastUpdate (); 125 | 126 | protected abstract void setChartCycle (ChartCycleData value); 127 | 128 | /** 129 | * Determine if the cycle client cache need to be updated 130 | * @return true if the cache needs to be updated, false otherwise 131 | */ 132 | public abstract boolean isUpdateRequired (); 133 | 134 | /** 135 | * Construct the URL to call the airspace cycle client denodo web service. 136 | * 137 | * @param targetDate the date used in construction of the web target url 138 | * @return 139 | */ 140 | public abstract String getWebTarget (Date targetDate); 141 | 142 | } 143 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/VFRFunctionalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | import static org.junit.Assert.fail; 19 | 20 | import org.junit.Test; 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | 24 | import gov.faa.ait.apra.api.VFRCharts; 25 | import gov.faa.ait.apra.jaxb.ProductSet; 26 | 27 | public class VFRFunctionalTest { 28 | private static final Logger logger = LoggerFactory.getLogger(VFRFunctionalTest.class); 29 | private VFRCharts vfr; 30 | 31 | public VFRFunctionalTest () { 32 | vfr = new VFRCharts(); 33 | } 34 | 35 | @Test 36 | public void testProductReleseCurrent() { 37 | vfr = new VFRCharts(); 38 | ProductSet ps = (ProductSet) vfr.getGrandCanyonRelease("current").getEntity(); 39 | logger.info("VFR Product Relese Test for 'current' return url of "+ps.getEdition().get(0).getProduct().getUrl()); 40 | assertTrue(VerifyValues.verifyURL(ps.getEdition().get(0).getProduct().getUrl())); 41 | } 42 | 43 | @Test 44 | public void testProductEditionCurrent() { 45 | vfr = new VFRCharts(); 46 | ProductSet ps = (ProductSet) vfr.getGrandCanyonEdition("current").getEntity(); 47 | logger.info("VFR Product Edition Test for 'current' return code "+ps.getStatus().getCode().intValue()); 48 | int code = ps.getStatus().getCode().intValue(); 49 | assertEquals(code, 200); 50 | } 51 | 52 | @Test 53 | public void testProductReleseNext() { 54 | vfr = new VFRCharts(); 55 | ProductSet ps = (ProductSet) vfr.getGrandCanyonRelease("next").getEntity(); 56 | logger.info("VFR Product Edition Test for 'Next' return code "+ps.getStatus().getCode().intValue()); 57 | int code = ps.getStatus().getCode().intValue(); 58 | assertEquals(code, 404); 59 | } 60 | 61 | @Test 62 | public void testProductEditionNext() { 63 | vfr = new VFRCharts(); 64 | ProductSet ps = (ProductSet) vfr.getGrandCanyonEdition("next").getEntity(); 65 | int code = ps.getStatus().getCode().intValue(); 66 | logger.info("VFR Product Edition Test for 'next' return code "+ps.getStatus().getCode().intValue()); 67 | 68 | switch (code) { 69 | case 200: assertEquals(new Integer(200), new Integer(code)); 70 | break; 71 | case 404: assertEquals(new Integer(404), new Integer(code)); 72 | break; 73 | 74 | default: 75 | fail(); 76 | } 77 | } 78 | 79 | 80 | 81 | // Negative tests 82 | 83 | @Test 84 | public void testProductEditionTypo() { 85 | vfr = new VFRCharts(); 86 | ProductSet ps = (ProductSet) vfr.getGrandCanyonEdition("TYPO").getEntity(); 87 | int code = ps.getStatus().getCode().intValue(); 88 | logger.info("VFR Product Edition Test for 'incorrect edition' return code "+ps.getStatus().getCode().intValue()); 89 | assertEquals(code, 400); 90 | } 91 | 92 | @Test 93 | public void testProductReleaseTypo() { 94 | vfr = new VFRCharts(); 95 | ProductSet ps = (ProductSet) vfr.getGrandCanyonRelease("TYPO").getEntity(); 96 | int code = ps.getStatus().getCode().intValue(); 97 | logger.info("VFR Product Relese Test for 'incorrect Release' return code "+ps.getStatus().getCode().intValue()); 98 | assertEquals(code, 400); 99 | } 100 | 101 | @Test 102 | public void testProductEditionGeoTypo() { 103 | vfr = new VFRCharts(); 104 | ProductSet ps = (ProductSet) vfr.getGrandCanyonEdition("").getEntity(); 105 | int code = ps.getStatus().getCode().intValue(); 106 | logger.info("VFR Product Edition Test for 'incorrect Geo' return code "+ps.getStatus().getCode().intValue()); 107 | assertEquals(code, 200); 108 | } 109 | 110 | @Test 111 | public void testProductReleaseGeoTypo() { 112 | vfr = new VFRCharts(); 113 | ProductSet ps = (ProductSet) vfr.getGrandCanyonRelease("").getEntity(); 114 | int code = ps.getStatus().getCode().intValue(); 115 | logger.info("VFR Product Release Test for 'incorrect Geo' return code "+ps.getStatus().getCode().intValue()); 116 | assertEquals(code, 200); 117 | } 118 | 119 | @Test 120 | public void testProductEditionTypoTypo() { 121 | vfr = new VFRCharts(); 122 | ProductSet ps = (ProductSet) vfr.getGrandCanyonEdition("Typo").getEntity(); 123 | int code = ps.getStatus().getCode().intValue(); 124 | logger.info("VFR Product Edition Test for 'incorrect edition and geo' return code "+ps.getStatus().getCode().intValue()); 125 | assertEquals(code, 400); 126 | } 127 | 128 | @Test 129 | public void testProductReleaseFmtTypoTypo() { 130 | vfr = new VFRCharts(); 131 | ProductSet ps = (ProductSet) vfr.getGrandCanyonRelease("Typo").getEntity(); 132 | int code = ps.getStatus().getCode().intValue(); 133 | logger.info("VFR Product Release Test for 'incorrect Release and geo' return code "+ps.getStatus().getCode().intValue()); 134 | assertEquals(code, 400); 135 | } 136 | 137 | @Test 138 | public void testProductReleseDefault() { 139 | vfr = new VFRCharts(); 140 | ProductSet ps = (ProductSet) vfr.getGrandCanyonRelease("").getEntity(); 141 | int code = ps.getStatus().getCode().intValue(); 142 | logger.info("VFR Product Edition Test for 'empty and empty' return code "+ps.getStatus().getCode().intValue()); 143 | assertEquals(code, 200); 144 | } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/GOMTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import org.junit.Test; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | 22 | import gov.faa.ait.apra.api.GulfOfMexicoEnrouteCharts; 23 | import gov.faa.ait.apra.jaxb.ProductSet; 24 | import gov.faa.ait.apra.cycle.VFRChartCycleClient; 25 | 26 | public class GOMTest { 27 | private final static Logger logger = LoggerFactory.getLogger(GOMTest.class); 28 | 29 | private GulfOfMexicoEnrouteCharts gom; 30 | 31 | public GOMTest () { 32 | gom = new GulfOfMexicoEnrouteCharts(); 33 | } 34 | 35 | @Test 36 | public void testDownloadOperations() { 37 | VFRChartCycleClient client = new VFRChartCycleClient("IFR_PGOM"); 38 | 39 | ProductSet current = gom.getRelease(client.getCurrentCycle()); 40 | 41 | if (current.getEdition().size() > 0) 42 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 43 | 44 | ProductSet next = gom.getRelease(client.getNextCycle()); 45 | if (next.getEdition().size() > 0) 46 | logger.info(next.getEdition().get(0).getProduct().getUrl()); 47 | } 48 | 49 | @Test 50 | public void testEditionOperations() { 51 | VFRChartCycleClient client = new VFRChartCycleClient("IFR_PGOM"); 52 | 53 | ProductSet current = gom.getEdition(client.getCurrentCycle()); 54 | assertEquals(Integer.valueOf(current.getStatus().getCode()), Integer.valueOf(200)); 55 | 56 | ProductSet next = gom.getEdition(client.getNextCycle()); 57 | assertEquals(Integer.valueOf(next.getStatus().getCode()), Integer.valueOf(200)); 58 | } 59 | 60 | @Test 61 | public void testGOMWest() { 62 | 63 | ProductSet current = (ProductSet) gom.getGOMRelease("current", null, "west").getEntity(); 64 | 65 | if (current.getEdition().size() > 0) 66 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 67 | } 68 | 69 | @Test 70 | public void testGOMCentral() { 71 | 72 | ProductSet current = (ProductSet) gom.getGOMRelease("current", "PDF", "central").getEntity(); 73 | 74 | if (current.getEdition().size() > 0) 75 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 76 | } 77 | 78 | @Test 79 | public void testGOMCurrent() { 80 | 81 | ProductSet current = (ProductSet) gom.getGOMRelease("current", null, null).getEntity(); 82 | 83 | if (current.getEdition().size() > 0) 84 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 85 | } 86 | 87 | @Test 88 | public void testGOMBadGeoname() { 89 | 90 | ProductSet next = (ProductSet) gom.getGOMRelease("current", "PDF", "fubar").getEntity(); 91 | 92 | assertEquals(Integer.valueOf(next.getStatus().getCode()), Integer.valueOf(400)); 93 | } 94 | 95 | @Test 96 | public void testGOMNulls() { 97 | VFRChartCycleClient client = new VFRChartCycleClient("IFR_PGOM"); 98 | client.getCurrentCycle(); 99 | 100 | ProductSet current = (ProductSet) gom.getGOMRelease(null, null, null).getEntity(); 101 | 102 | assertEquals(Integer.valueOf(200), Integer.valueOf(current.getStatus().getCode())); 103 | } 104 | 105 | @Test 106 | public void testGOMJunk() { 107 | 108 | ProductSet next = (ProductSet) gom.getGOMRelease("junk", "foo", "morejunk").getEntity(); 109 | 110 | assertEquals(Integer.valueOf(next.getStatus().getCode()), Integer.valueOf(400)); 111 | } 112 | 113 | 114 | 115 | @Test 116 | public void testGOMTIFFWest() { 117 | 118 | ProductSet current = (ProductSet) gom.getGOMRelease("current", "TIFF", "west").getEntity(); 119 | 120 | if (current.getEdition().size() > 0) 121 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 122 | } 123 | 124 | @Test 125 | public void testGOMTIFFCentral() { 126 | 127 | ProductSet current = (ProductSet) gom.getGOMRelease("current", "TIFF", "central").getEntity(); 128 | 129 | if (current.getEdition().size() > 0) 130 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 131 | } 132 | 133 | @Test 134 | public void testGOMTIFFCurrent() { 135 | 136 | ProductSet current = (ProductSet) gom.getGOMRelease("current", "TIFF", null).getEntity(); 137 | 138 | if (current.getEdition().size() > 0) 139 | logger.info(current.getEdition().get(0).getProduct().getUrl()); 140 | } 141 | 142 | @Test 143 | public void testGOMTIFFBadGeoname() { 144 | 145 | ProductSet next = (ProductSet) gom.getGOMRelease("current", "TIFF", "fubar").getEntity(); 146 | 147 | assertEquals(Integer.valueOf(next.getStatus().getCode()), Integer.valueOf(400)); 148 | } 149 | 150 | @Test 151 | public void testGOMTIFFNulls() { 152 | VFRChartCycleClient client = new VFRChartCycleClient("IFR_PGOM"); 153 | client.getCurrentCycle(); 154 | 155 | ProductSet current = (ProductSet) gom.getGOMRelease(null, "TIFF", null).getEntity(); 156 | 157 | assertEquals(Integer.valueOf(200), Integer.valueOf(current.getStatus().getCode())); 158 | } 159 | 160 | @Test 161 | public void testGOMTIFFJunk() { 162 | 163 | ProductSet next = (ProductSet) gom.getGOMRelease("junk", "TIFF", "morejunk").getEntity(); 164 | 165 | assertEquals(Integer.valueOf(next.getStatus().getCode()), Integer.valueOf(400)); 166 | } 167 | 168 | 169 | } 170 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/CIFP2Test.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | import static org.junit.Assert.fail; 19 | 20 | import javax.ws.rs.core.Response; 21 | 22 | import org.junit.Test; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | import gov.faa.ait.apra.api.CIFP; 27 | import gov.faa.ait.apra.jaxb.ProductSet; 28 | import gov.faa.ait.apra.cycle.ChartCycleClient; 29 | 30 | public class CIFP2Test { 31 | private CIFP cifp; 32 | private static final Logger logger = LoggerFactory.getLogger(CIFP2Test.class); 33 | 34 | public CIFP2Test () { 35 | ChartCycleClient client = new ChartCycleClient(); 36 | client.forceUpdate(); 37 | } 38 | 39 | @Test 40 | public void testCurrentRelease() { 41 | cifp = new CIFP(); 42 | Response ps = cifp.getCIFPRelease("current"); 43 | int code = ps.getStatus(); 44 | assertEquals(code, 200); 45 | ProductSet psEntity = (ProductSet) ps.getEntity(); 46 | assertTrue(VerifyValues.verifyURL(psEntity.getEdition().get(0).getProduct().getUrl())); 47 | } 48 | 49 | @Test 50 | public void testNextRelease() { 51 | cifp = new CIFP(); 52 | Response ps = cifp.getCIFPRelease("next"); 53 | int code = ps.getStatus(); 54 | 55 | // Have to allow for either a positive response or a not found due to the AJV release cycle. A "next" edition may 56 | // only be published 20 days in advance. Therefore, there is a time period when we may ask for "next", but it really hasn't 57 | // been put on the web site yet 58 | if (! (code == 200 || code == 404) ) { 59 | fail(); 60 | } 61 | } 62 | 63 | @Test 64 | public void testNullRelease() { 65 | cifp = new CIFP(); 66 | ProductSet ps = (ProductSet) cifp.getCIFPRelease(null).getEntity(); 67 | int code = ps.getStatus().getCode().intValue(); 68 | assertEquals(code, 200); 69 | assertTrue(VerifyValues.verifyURL(ps.getEdition().get(0).getProduct().getUrl())); 70 | } 71 | 72 | @Test 73 | public void testFooRelease() { 74 | cifp = new CIFP(); 75 | ProductSet ps = (ProductSet) cifp.getCIFPRelease("foo").getEntity(); 76 | int code = ps.getStatus().getCode().intValue(); 77 | assertEquals(code, 400); 78 | } 79 | 80 | @Test 81 | public void testDollarRelease() { 82 | cifp = new CIFP(); 83 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("$format").getEntity(); 84 | int code = ps.getStatus().getCode().intValue(); 85 | assertEquals(code, 400); 86 | } 87 | 88 | @Test 89 | public void testWildcardRelease() { 90 | cifp = new CIFP(); 91 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("*").getEntity(); 92 | int code = ps.getStatus().getCode().intValue(); 93 | assertEquals(code, 400); 94 | } 95 | 96 | @Test 97 | public void testSqlWildcardRelease() { 98 | cifp = new CIFP(); 99 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("%").getEntity(); 100 | int code = ps.getStatus().getCode().intValue(); 101 | assertEquals(code, 400); 102 | } 103 | 104 | @Test 105 | public void testRandomJunkRelease() { 106 | cifp = new CIFP(); 107 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("%20*x%$(\\./").getEntity(); 108 | int code = ps.getStatus().getCode().intValue(); 109 | assertEquals(code, 400); 110 | } 111 | 112 | @Test 113 | public void testCurrentEdition() { 114 | cifp = new CIFP(); 115 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("current").getEntity(); 116 | int code = ps.getStatus().getCode().intValue(); 117 | assertEquals(code, 200); 118 | } 119 | 120 | @Test 121 | public void testNextEdition() { 122 | cifp = new CIFP(); 123 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("next").getEntity(); 124 | int code = ps.getStatus().getCode().intValue(); 125 | assertEquals(code, 200); 126 | } 127 | 128 | @Test 129 | public void testNullEdition() { 130 | cifp = new CIFP(); 131 | ProductSet ps = (ProductSet) cifp.getCIFPEdition(null).getEntity(); 132 | int code = ps.getStatus().getCode().intValue(); 133 | assertEquals(code, 200); 134 | } 135 | 136 | @Test 137 | public void testFooEdition() { 138 | cifp = new CIFP(); 139 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("foo").getEntity(); 140 | int code = ps.getStatus().getCode().intValue(); 141 | assertEquals(code, 400); 142 | } 143 | 144 | @Test 145 | public void testDollarEdition() { 146 | cifp = new CIFP(); 147 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("$format").getEntity(); 148 | int code = ps.getStatus().getCode().intValue(); 149 | assertEquals(code, 400); 150 | } 151 | 152 | @Test 153 | public void testWildcardEdition() { 154 | cifp = new CIFP(); 155 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("*").getEntity(); 156 | int code = ps.getStatus().getCode().intValue(); 157 | assertEquals(code, 400); 158 | } 159 | 160 | @Test 161 | public void testSqlWildcardEdition() { 162 | cifp = new CIFP(); 163 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("%").getEntity(); 164 | int code = ps.getStatus().getCode().intValue(); 165 | assertEquals(code, 400); 166 | } 167 | 168 | @Test 169 | public void testRandomJunkEdition() { 170 | cifp = new CIFP(); 171 | ProductSet ps = (ProductSet) cifp.getCIFPEdition("%2F*@#$(())@#*(@#$)").getEntity(); 172 | int code = ps.getStatus().getCode().intValue(); 173 | assertEquals(code, 400); 174 | } 175 | 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/cycle/HelicopterChartCycleClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.cycle; 15 | 16 | import java.text.SimpleDateFormat; 17 | import java.util.Date; 18 | import java.util.concurrent.TimeUnit; 19 | 20 | import javax.ws.rs.client.Client; 21 | import javax.ws.rs.client.ClientBuilder; 22 | import javax.ws.rs.client.WebTarget; 23 | import javax.ws.rs.core.MediaType; 24 | 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | import com.fasterxml.jackson.databind.DeserializationFeature; 29 | import com.fasterxml.jackson.databind.ObjectMapper; 30 | import com.google.common.base.Charsets; 31 | 32 | import gov.faa.ait.apra.bootstrap.Config; 33 | import gov.faa.ait.apra.cycle.ChartCycleData; 34 | import gov.faa.ait.apra.cycle.ChartCycleElementsJson; 35 | 36 | /** 37 | * 38 | * @author FAA 39 | * 40 | */ 41 | 42 | public class HelicopterChartCycleClient { 43 | private static final Logger logger = LoggerFactory 44 | .getLogger(HelicopterChartCycleClient.class); 45 | private ChartCycleData cycle = null; 46 | private Date lastUpdate = null; 47 | private Date today; 48 | private String chartCycleTypeCode; 49 | private String city; 50 | 51 | /** 52 | * Helicopter Chart Cycle Client with city name. 53 | * 54 | * @param cityName 55 | */ 56 | public HelicopterChartCycleClient(String cityName) { 57 | 58 | // default to the Grand Canyon type code to avoid breaking Grand Canyon 59 | // service 60 | chartCycleTypeCode = "Helicopter_VFR"; 61 | try { 62 | city = java.net.URLEncoder.encode(cityName, "UTF-8").replace("+", 63 | "%20"); 64 | this.today = new Date(System.currentTimeMillis()); 65 | 66 | if (this.isUpdateRequired()) { 67 | lastUpdate = new Date(System.currentTimeMillis()); 68 | cycle = getChartCycle(); 69 | } 70 | logger.info("city " + city); 71 | 72 | } catch (Exception e) { 73 | logger.error(" HelicopterChartCycleClient ", e); 74 | } 75 | } 76 | 77 | /** 78 | * 79 | * @return 80 | */ 81 | 82 | public ChartCycleData getChartCycle() { 83 | return getChartCycle(today, false); 84 | } 85 | 86 | /** 87 | * dd 88 | */ 89 | public void forceUpdate() { 90 | getChartCycle(today, true); 91 | } 92 | 93 | /** 94 | * 95 | * @param forceUpdate 96 | * @return 97 | */ 98 | public ChartCycleData getChartCycle(boolean forceUpdate) { 99 | return getChartCycle(today, forceUpdate); 100 | } 101 | 102 | /** 103 | * 104 | * @param targetDate 105 | * @param forceUpdate 106 | * @return 107 | */ 108 | public ChartCycleData getChartCycle(Date targetDate, boolean forceUpdate) { 109 | StringBuilder url = new StringBuilder(); 110 | 111 | if (forceUpdate) { 112 | lastUpdate = new Date(System.currentTimeMillis()); 113 | cycle = null; 114 | } 115 | url = url.append(Config.getDenodoHost() 116 | + Config.getDenodoVFRCycleResource()); 117 | SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); 118 | 119 | String dateString = formatter.format(targetDate); 120 | 121 | StringBuilder queryString = new StringBuilder(); 122 | queryString = queryString.append("?query_date=" + dateString); 123 | queryString = queryString.append("&chart_cycle_type_code=" 124 | + chartCycleTypeCode); 125 | queryString = queryString.append("&chart_city_name=" + this.city); 126 | queryString = queryString.append("&%24format=json"); 127 | 128 | url = url.append(queryString); 129 | logger.info("Calling denodo for Helicopter chart cycle at " 130 | + url.toString()); 131 | 132 | if (cycle != null && lastUpdate != null) { 133 | return cycle; 134 | } 135 | 136 | lastUpdate = new Date(System.currentTimeMillis()); 137 | 138 | String unbound = ""; 139 | 140 | try { 141 | Client client = ClientBuilder.newClient(); 142 | 143 | WebTarget webTarget = client.target(url.toString()); 144 | long now = System.currentTimeMillis(); 145 | unbound = webTarget.request(MediaType.APPLICATION_XML_TYPE).get( 146 | String.class); 147 | long duration = System.currentTimeMillis() - now; 148 | logger.info("Call for Helicopter chart cycle took " + duration 149 | + " ms"); 150 | ObjectMapper mapper = new ObjectMapper(); 151 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, 152 | false); 153 | mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); 154 | cycle = mapper.readValue(unbound.getBytes(Charsets.UTF_16), ChartCycleData.class); 155 | } catch (Exception ex) { 156 | logger.error("getChartCycle", ex); 157 | cycle = null; 158 | return null; 159 | } 160 | return cycle; 161 | } 162 | 163 | private boolean isUpdateRequired() { 164 | if (lastUpdate == null || cycle == null) { 165 | return true; 166 | } 167 | 168 | long diff = today.getTime() - lastUpdate.getTime(); 169 | long hours = TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS); 170 | 171 | return hours >= Config.getCycleAgeLimit(); 172 | } 173 | 174 | private ChartCycleElementsJson getCycle(String periodCode) { 175 | if (this.isUpdateRequired()) { 176 | getChartCycle(); 177 | } 178 | 179 | boolean found; 180 | 181 | ChartCycleElementsJson[] elements = cycle.getElements(); 182 | for (int i = 0; i < elements.length; i++) { 183 | ChartCycleElementsJson element = elements[i]; 184 | found = element.getChart_cycle_period_code().equalsIgnoreCase( 185 | periodCode); 186 | if (found) { 187 | return element; 188 | } 189 | } 190 | return null; 191 | } 192 | 193 | public ChartCycleElementsJson getNextCycle() { 194 | 195 | return getCycle("NEXT"); 196 | } 197 | 198 | public ChartCycleElementsJson getCurrentCycle() { 199 | return getCycle("CURRENT"); 200 | } 201 | 202 | } 203 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/HelicopterFunctionalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | 19 | import org.junit.Test; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | 23 | import gov.faa.ait.apra.api.HelicopterCharts; 24 | import gov.faa.ait.apra.jaxb.ProductSet; 25 | 26 | public class HelicopterFunctionalTest { 27 | private static final Logger logger = LoggerFactory 28 | .getLogger(HelicopterFunctionalTest.class); 29 | private HelicopterCharts helicopter; 30 | private String cities[] = { 31 | 32 | "Boston Heli", "Chicago Heli", "Detroit Heli", "Houston Heli", 33 | "Los Angeles Heli", "New York Heli", "Baltimore Washington Heli", 34 | "Dallas Ft. Worth Heli", "U.S Gulf Coast" }; 35 | 36 | public HelicopterFunctionalTest () { 37 | helicopter = new HelicopterCharts(); 38 | } 39 | 40 | @Test 41 | public void testProductReleseDefault() { 42 | 43 | for (String city : cities) { 44 | ProductSet ps = (ProductSet) helicopter.getHelicopterRelease("", null, city).getEntity(); 45 | 46 | if ((ps.getEdition() != null && !ps.getEdition().isEmpty() && ps.getEdition().get(0).getEditionDate() != null) 47 | && (!ps.getEdition().get(0).getEditionDate().isEmpty())) { 48 | logger.info("Helicopter Product Relese test for 'Default parameters' return url of " 49 | + ps.getEdition().get(0).getProduct().getUrl()); 50 | assertTrue(VerifyValues.verifyURL(ps.getEdition().get(0) 51 | .getProduct().getUrl())); 52 | } 53 | } 54 | 55 | } 56 | 57 | 58 | @Test 59 | public void testProductReleseCurrent() { 60 | helicopter = new HelicopterCharts(); 61 | for (String city : cities) { 62 | ProductSet ps = (ProductSet) helicopter.getHelicopterRelease("current", "PDF", city).getEntity(); 63 | logger.info("Helicopter Product Relese Test for 'current' return url of " 64 | + ps.getEdition().get(0).getProduct().getUrl()); 65 | if (ps.getEdition().get(0).getProduct().getUrl() != null) { 66 | 67 | assertTrue(VerifyValues.verifyURL(ps.getEdition().get(0) 68 | .getProduct().getUrl())); 69 | } 70 | } 71 | } 72 | 73 | @Test 74 | public void testProductEditionDefault() { 75 | helicopter = new HelicopterCharts(); 76 | for (String city : cities) { 77 | ProductSet ps = (ProductSet) helicopter.getHelicopterEdition("", city).getEntity(); 78 | logger.info("Helicopter Product Edition Test for 'Default parameters' return code " 79 | + ps.getStatus().getCode().intValue()); 80 | int code = ps.getStatus().getCode().intValue(); 81 | assertEquals(code, 400); 82 | } 83 | } 84 | 85 | @Test 86 | public void testProductEditionCurrent() { 87 | helicopter = new HelicopterCharts(); 88 | for (String city : cities) { 89 | ProductSet ps = (ProductSet) helicopter.getHelicopterEdition("current", city).getEntity(); 90 | logger.info("Helicopter Product Edition Test for 'current' return code " 91 | + ps.getStatus().getCode().intValue()); 92 | int code = ps.getStatus().getCode().intValue(); 93 | assertEquals(code, 200); 94 | } 95 | } 96 | 97 | // Negative tests 98 | @Test 99 | public void testProductEditionTypo() { 100 | helicopter = new HelicopterCharts(); 101 | ProductSet ps = (ProductSet) helicopter.getHelicopterEdition("TYPO", "Boston Heli").getEntity(); 102 | int code = ps.getStatus().getCode().intValue(); 103 | logger.info("Helicopter Product Edition Test for 'incorrect edition' return code " 104 | + ps.getStatus().getCode().intValue()); 105 | assertEquals(code, 400); 106 | } 107 | 108 | @Test 109 | public void testProductReleaseTypo() { 110 | helicopter = new HelicopterCharts(); 111 | ProductSet ps = (ProductSet) helicopter.getHelicopterRelease("TYPO", "PDF", "Boston Heli").getEntity(); 112 | int code = ps.getStatus().getCode().intValue(); 113 | logger.info("Helicopter Product Relese Test for 'incorrect Release' return code " 114 | + ps.getStatus().getCode().intValue()); 115 | assertEquals(code, 400); 116 | } 117 | 118 | @Test 119 | public void testProductEditionGeoTypo() { 120 | helicopter = new HelicopterCharts(); 121 | ProductSet ps = (ProductSet) helicopter.getHelicopterEdition("", "Typo").getEntity(); 122 | int code = ps.getStatus().getCode().intValue(); 123 | logger.info("Helicopter Product Edition Test for 'incorrect city' return code " 124 | + ps.getStatus().getCode().intValue()); 125 | assertEquals(code, 400); 126 | } 127 | 128 | @Test 129 | public void testProductReleaseGeoTypo() { 130 | helicopter = new HelicopterCharts(); 131 | ProductSet ps = (ProductSet) helicopter.getHelicopterRelease("", "PDF", "Typo").getEntity(); 132 | int code = ps.getStatus().getCode().intValue(); 133 | logger.info("Helicopter Product Release Test for 'incorrect city' return code " 134 | + ps.getStatus().getCode().intValue()); 135 | assertEquals(code, 400); 136 | } 137 | 138 | @Test 139 | public void testProductEditionTypoTypo() { 140 | helicopter = new HelicopterCharts(); 141 | ProductSet ps = (ProductSet) helicopter.getHelicopterEdition("Typo", "Typo").getEntity(); 142 | int code = ps.getStatus().getCode().intValue(); 143 | logger.info("Helicopter Product Edition Test for 'incorrect edition and Fmt' return code " 144 | + ps.getStatus().getCode().intValue()); 145 | assertEquals(code, 400); 146 | } 147 | 148 | @Test 149 | public void testProductReleaseFmtTypoTypo() { 150 | helicopter = new HelicopterCharts(); 151 | ProductSet ps = (ProductSet) helicopter.getHelicopterRelease("Typo", "PDF", "Typo").getEntity(); 152 | int code = ps.getStatus().getCode().intValue(); 153 | logger.info("Helicopter Product Release Test for 'incorrect Release and city' return code " 154 | + ps.getStatus().getCode().intValue()); 155 | assertEquals(code, 400); 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/util/CycleDateUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.util; 15 | 16 | import java.util.Calendar; 17 | import java.util.Date; 18 | import java.util.GregorianCalendar; 19 | import java.util.TimeZone; 20 | import java.util.concurrent.TimeUnit; 21 | 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | 25 | import gov.faa.ait.apra.cycle.ChartCycleClient; 26 | 27 | /** 28 | * This class is used to expand calculation of cycle dates beyond the current and next cycles. 29 | * The utility uses a calendar to calculate the next after next and previous dates for both 30 | * the 28 day and 56 day airspace cycle 31 | * @author FAA 32 | * 33 | */ 34 | public class CycleDateUtil { 35 | private static final Logger logger = LoggerFactory.getLogger(CycleDateUtil.class); 36 | private ChartCycleClient cycleClient; 37 | 38 | /** 39 | * Default constructor initializes the cycle from the denodo data source 40 | */ 41 | public CycleDateUtil () { 42 | cycleClient = new ChartCycleClient(); 43 | } 44 | 45 | /** 46 | * Get the current cycle date 47 | * @return the current cycle date 48 | */ 49 | public Date getCurrentCycle () { 50 | logger.info("Cycle client in CycleDateUtil is instanceof "+cycleClient.getClass().getName()); 51 | return cycleClient.getCurrentCycle().getChart_effective_date(); 52 | } 53 | 54 | /** 55 | * Get the next cycle date 56 | * @return the next cycle date 57 | */ 58 | public Date getNextCycle () { 59 | return cycleClient.getNextCycle().getChart_effective_date(); 60 | } 61 | 62 | /** 63 | * Get the current 56 day cycle date 64 | * @return the current 56 day cycle date 65 | */ 66 | public Date getCurrent56Day () { 67 | return cycleClient.getCurrent56DayCycle().getChart_effective_date(); 68 | } 69 | 70 | /** 71 | * Get the next 56 day cycle date 72 | * @return the next 56 day cycle date 73 | */ 74 | public Date getNext56Day () { 75 | return cycleClient.getNext56DayCycle().getChart_effective_date(); 76 | } 77 | 78 | /** 79 | * Get the previous 56 day cycle date. This provides the cycle date that is 1 cycle 80 | * prior to the current cycle date. 81 | * @return the next after next 56 day cycle date 82 | */ 83 | public Date getPrevious56Day () { 84 | return get56DayCycleDate(-1); 85 | } 86 | 87 | /** 88 | * Get the 56 day cycle date by incrementing or decrementing the number of cycles from 89 | * the current 56 day cycle date. To get the previous cycle date, the increment = -1. 90 | * To get the "next after next" cycle date, advance 2 cycles and increment = 2. An 91 | * increment value of 0 returns the current 56 day cycle date 92 | * @param increment 93 | * @return 94 | */ 95 | public Date get56DayCycleDate (int increment) { 96 | GregorianCalendar calendar = new GregorianCalendar(TimeZone.getDefault()); 97 | calendar.setTime(getCurrent56Day()); 98 | calendar.add(Calendar.DATE, 56*increment); 99 | return calendar.getTime(); 100 | } 101 | 102 | /** 103 | * Get the current 28 day cycle date 104 | * @return the current 28 day cycle date 105 | */ 106 | public Date getCurrent28Day () { 107 | return cycleClient.getCurrent28DayCycle().getChart_effective_date(); 108 | } 109 | 110 | /** 111 | * Get the next 28 day cycle date 112 | * @return the next 28 date cycle date 113 | */ 114 | public Date getNext28Day () { 115 | return cycleClient.getNext28DayCycle().getChart_effective_date(); 116 | } 117 | 118 | /** 119 | * Get the previous 28 day cycle date. This provides the cycle date that is 1 cycle 120 | * prior to the current cycle date. 121 | * @return the next after next 28 day cycle date 122 | */ 123 | public Date getPrevious28Day () { 124 | return get28DayCycleDate(-1); 125 | } 126 | 127 | /** 128 | * Get the 28 day cycle date by incrementing or decrementing the number of cycles from 129 | * the current 28 day cycle date. To get the previous cycle date, the increment = -1. 130 | * To get the "next after next" cycle date, advance 2 cycles and increment = 2. An 131 | * increment value of 0 returns the current 28 day cycle date 132 | * @param increment 133 | * @return 134 | */ 135 | public Date get28DayCycleDate (int increment) { 136 | GregorianCalendar calendar = new GregorianCalendar(TimeZone.getDefault()); 137 | calendar.setTime(getCurrent28Day()); 138 | calendar.add(Calendar.DATE, 28*increment); 139 | return calendar.getTime(); 140 | } 141 | 142 | /** 143 | * Get the cycle number for the digital enroute charts. This is a sequential number that increments 144 | * by one (1) every 56 days. This starts with an epoch date and cycle of 09/15/2016 and cycle number of 32 145 | * @return the current DEC cycle number 146 | */ 147 | public static int getCurrentDECCycleNumber () { 148 | GregorianCalendar now = new GregorianCalendar (TimeZone.getDefault()); 149 | now.setTimeInMillis(System.currentTimeMillis()); 150 | return CycleDateUtil.getDECCycleNumber(now); 151 | } 152 | 153 | public static int getNextDECCycleNumber () { 154 | return CycleDateUtil.getCurrentDECCycleNumber() + 1; 155 | } 156 | 157 | public static int getDECCycleNumber (Calendar startDate) { 158 | GregorianCalendar epoch = new GregorianCalendar(TimeZone.getDefault()); 159 | 160 | // Set the epoch to October 20, 2011 00:01:00 161 | epoch.set(2011, 9, 20, 0, 1, 0); 162 | 163 | if (logger.isDebugEnabled()) { 164 | logger.debug("Using startDate of "+startDate.toString()); 165 | logger.debug("Using epoch Date of "+epoch.toString()); 166 | } 167 | 168 | long diff = startDate.getTimeInMillis() - epoch.getTimeInMillis(); 169 | long days = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS); 170 | 171 | if (logger.isDebugEnabled()) { 172 | logger.debug("Number of days since epoch is "+days+". Returning cycle number "+Math.floor(days/56d)); 173 | } 174 | 175 | return (int) Math.floor(days / 56d)+1; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/cycle/WallPlanningChartCycleClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.cycle; 15 | 16 | import java.text.SimpleDateFormat; 17 | import java.util.Date; 18 | import java.util.concurrent.TimeUnit; 19 | 20 | import javax.ws.rs.client.Client; 21 | import javax.ws.rs.client.ClientBuilder; 22 | import javax.ws.rs.client.WebTarget; 23 | import javax.ws.rs.core.MediaType; 24 | 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | import com.fasterxml.jackson.databind.DeserializationFeature; 29 | import com.fasterxml.jackson.databind.ObjectMapper; 30 | import com.google.common.base.Charsets; 31 | 32 | import gov.faa.ait.apra.bootstrap.Config; 33 | 34 | /** 35 | * 36 | * @author FAA 37 | * 38 | */ 39 | public class WallPlanningChartCycleClient extends DenodoClient { 40 | private static final Logger logger = LoggerFactory 41 | .getLogger(WallPlanningChartCycleClient.class); 42 | private static ChartCycleData wpCycle; 43 | private static Date wpLastUpdate; 44 | private Date today; 45 | 46 | public WallPlanningChartCycleClient() { 47 | this.today = new Date(System.currentTimeMillis()); 48 | 49 | if (this.isUpdateRequired()) { 50 | setLastUpdate(); 51 | setChartCycle(getChartCycle(true)); 52 | } 53 | } 54 | 55 | @Override 56 | public ChartCycleData getChartCycle() { 57 | if (! isUpdateRequired()) { 58 | return WallPlanningChartCycleClient.wpCycle; 59 | } 60 | 61 | return forceUpdate(); 62 | } 63 | 64 | /** 65 | * 66 | * @param targetDate 67 | * @param forceUpdate 68 | * @return 69 | */ 70 | 71 | public ChartCycleData getChartCycle(Date targetDate, boolean forceUpdate) { 72 | ChartCycleData cycleData; 73 | StringBuilder url = new StringBuilder(); 74 | 75 | if (forceUpdate) { 76 | setLastUpdate(); 77 | setChartCycle(null); 78 | } 79 | url = url.append(Config.getDenodoHost()+Config.getDenodoVFRCycleResource()); 80 | SimpleDateFormat formatter = new SimpleDateFormat ("MM/dd/yyyy"); 81 | 82 | String dateString = formatter.format(targetDate); 83 | 84 | StringBuilder queryString = new StringBuilder(); 85 | queryString = queryString.append("?query_date=" + dateString); 86 | queryString = queryString 87 | .append("&chart_cycle_type_code=Wall_Planning"); 88 | queryString = queryString.append("&%24format=json"); 89 | 90 | url = url.append(queryString); 91 | logger.info("Calling denodo for vfr chart cycle at " + url.toString()); 92 | 93 | if (wpCycle != null && wpLastUpdate != null) { 94 | return wpCycle; 95 | } 96 | 97 | setLastUpdate(); 98 | 99 | String unbound = ""; 100 | 101 | try { 102 | Client client = ClientBuilder.newClient(); 103 | 104 | WebTarget webTarget = client.target(url.toString()); 105 | long now = System.currentTimeMillis(); 106 | unbound = webTarget.request(MediaType.APPLICATION_XML_TYPE).get( 107 | String.class); 108 | long duration = System.currentTimeMillis() - now; 109 | logger.info("Call for WallPlan chart cycle took " + duration 110 | + " ms"); 111 | ObjectMapper mapper = new ObjectMapper(); 112 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, 113 | false); 114 | mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); 115 | cycleData = mapper.readValue(unbound.getBytes(Charsets.UTF_16), ChartCycleData.class); 116 | setChartCycle(cycleData); 117 | } catch (Exception ex) { 118 | logger.error("getChartCycle", ex); 119 | setChartCycle(null); 120 | return null; 121 | } 122 | return WallPlanningChartCycleClient.wpCycle; 123 | } 124 | 125 | 126 | @Override 127 | public boolean isUpdateRequired() { 128 | if (getLastUpdate() == null || WallPlanningChartCycleClient.wpCycle == null) { 129 | return true; 130 | } 131 | 132 | long diff = today.getTime() - getLastUpdate().getTime(); 133 | long hours = TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS); 134 | 135 | return hours >= Config.getCycleAgeLimit(); 136 | } 137 | 138 | public ChartCycleElementsJson getCycle(String periodCode) { 139 | if (this.isUpdateRequired()) { 140 | getChartCycle(true); 141 | } 142 | 143 | boolean found; 144 | 145 | ChartCycleElementsJson[] elements = getChartCycle().getElements(); 146 | for (int i = 0; i < elements.length; i++) { 147 | ChartCycleElementsJson element = elements[i]; 148 | found = element.getChart_cycle_period_code().equalsIgnoreCase( 149 | periodCode); 150 | if (found) { 151 | return element; 152 | } 153 | } 154 | return null; 155 | } 156 | 157 | /** 158 | * 159 | * @return 160 | */ 161 | public ChartCycleElementsJson getNextCycle() { 162 | 163 | return getCycle("NEXT"); 164 | } 165 | 166 | public ChartCycleElementsJson getCurrentCycle() { 167 | return getCycle("CURRENT"); 168 | } 169 | 170 | @Override 171 | public String getWebTarget (Date targetDate) { 172 | StringBuilder url = new StringBuilder(); 173 | 174 | url = url.append(Config.getDenodoHost()+Config.getDenodoVFRCycleResource()); 175 | SimpleDateFormat formatter = new SimpleDateFormat ("MM/dd/yyyy"); 176 | 177 | String dateString = formatter.format(targetDate); 178 | 179 | StringBuilder queryString = new StringBuilder(); 180 | queryString = queryString.append("?query_date=" + dateString); 181 | queryString = queryString 182 | .append("&chart_cycle_type_code=Wall_Planning"); 183 | queryString = queryString.append("&%24format=json"); 184 | 185 | url = url.append(queryString); 186 | return url.toString(); 187 | } 188 | 189 | @Override 190 | public Date getLastUpdate() { 191 | return WallPlanningChartCycleClient.wpLastUpdate; 192 | } 193 | 194 | @Override 195 | protected void setLastUpdate() { 196 | WallPlanningChartCycleClient.wpLastUpdate = new Date(System.currentTimeMillis()); 197 | 198 | } 199 | 200 | @Override 201 | protected void setChartCycle(ChartCycleData value) { 202 | WallPlanningChartCycleClient.wpCycle = value; 203 | } 204 | 205 | 206 | } 207 | -------------------------------------------------------------------------------- /src/test/java/gov/faa/ait/apra/test/SupplementFunctionalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.test; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | import gov.faa.ait.apra.api.SupplementCharts; 19 | import gov.faa.ait.apra.jaxb.ProductSet; 20 | 21 | import org.junit.Test; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | 25 | 26 | /** 27 | * test urls 28 | * http://localhost:8080/apra/supplement/info?edition=current&volume=NORTHWEST 29 | * http://localhost:8080/apra/supplement/info?edition=current&volume=SOUTHWEST 30 | * http://localhost:8080/apra/supplement/info?edition=current&volume=NORTH 31 | * CENTRAL 32 | * http://localhost:8080/apra/supplement/info?edition=current&volume=SOUTH 33 | * CENTRAL 34 | * http://localhost:8080/apra/supplement/info?edition=current&volume=EAST 35 | * CENTRAL 36 | * http://localhost:8080/apra/supplement/info?edition=current&volume=SOUTHEAST 37 | * http://localhost:8080/apra/supplement/info?edition=current&volume=NORTHEAST 38 | * http://localhost:8080/apra/supplement/info?edition=current&volume=PACIFIC 39 | * http://localhost:8080/apra/supplement/info?edition=current&volume=ALASKA 40 | * http://localhost:8080/apra/supplement/info?edition=next&volume=NORTHWEST 41 | * http://localhost:8080/apra/supplement/info?edition=next&volume=SOUTHWEST 42 | * http://localhost:8080/apra/supplement/info?edition=next&volume=NORTH CENTRAL 43 | * http://localhost:8080/apra/supplement/info?edition=next&volume=SOUTH CENTRAL 44 | * http://localhost:8080/apra/supplement/info?edition=next&volume=EAST CENTRAL 45 | * http://localhost:8080/apra/supplement/info?edition=next&volume=SOUTHEAST 46 | * http://localhost:8080/apra/supplement/info?edition=next&volume=NORTHEAST 47 | * http://localhost:8080/apra/supplement/info?edition=next&volume=PACIFIC 48 | * http://localhost:8080/apra/supplement/info?edition=next&volume=ALASKA 49 | * 50 | * @author FAA 51 | * 52 | */ 53 | public class SupplementFunctionalTest { 54 | private static final Logger logger = LoggerFactory 55 | .getLogger(SupplementFunctionalTest.class); 56 | private SupplementCharts supplement; 57 | private String cities[] = { "NORTHWEST", "SOUTHWEST", "NORTH CENTRAL", 58 | "SOUTH CENTRAL", "EAST CENTRAL", "SOUTHEAST", "NORTHEAST", 59 | "PACIFIC", "ALASKA" }; 60 | 61 | public SupplementFunctionalTest () { 62 | supplement = new SupplementCharts(); 63 | } 64 | 65 | @Test 66 | public void testProductReleseDefault() { 67 | 68 | for (String city : cities) { 69 | ProductSet ps = (ProductSet) supplement.getSupplementRelease("", city).getEntity(); 70 | 71 | if ((ps.getEdition() != null && !ps.getEdition().isEmpty() && ps 72 | .getEdition().get(0).getEditionDate() != null) 73 | && (!ps.getEdition().get(0).getEditionDate().isEmpty())) { 74 | logger.info("SupplementCharts Product Relese test for 'Default parameters' return url of " 75 | + ps.getEdition().get(0).getProduct().getUrl()); 76 | assertTrue(VerifyValues.verifyURL(ps.getEdition().get(0) 77 | .getProduct().getUrl())); 78 | } 79 | } 80 | 81 | } 82 | 83 | @Test 84 | public void testProductEditionDefault() { 85 | supplement = new SupplementCharts(); 86 | for (String city : cities) { 87 | ProductSet ps = (ProductSet) supplement.getSupplementEdition("", city).getEntity(); 88 | logger.info("Helicopter Product Edition Test for 'Default parameters' return code " 89 | + ps.getStatus().getCode().intValue()); 90 | int code = ps.getStatus().getCode().intValue(); 91 | assertEquals(code, 200); 92 | } 93 | } 94 | 95 | @Test 96 | public void testProductReleseDefaultUS() { 97 | 98 | supplement = new SupplementCharts(); 99 | ProductSet ps = (ProductSet) supplement.getSupplementRelease("", "").getEntity(); 100 | 101 | if ((ps.getEdition() != null && !ps.getEdition().isEmpty() && ps 102 | .getEdition().get(0).getEditionDate() != null) 103 | && (!ps.getEdition().get(0).getEditionDate().isEmpty())) { 104 | logger.info("SupplementCharts Product Relese test for 'Default parameters' return url of " 105 | + ps.getEdition().get(0).getProduct().getUrl()); 106 | assertTrue(VerifyValues.verifyURL(ps.getEdition().get(0) 107 | .getProduct().getUrl())); 108 | } 109 | 110 | } 111 | 112 | @Test 113 | public void testProductEditionDefaultUS() { 114 | supplement = new SupplementCharts(); 115 | ProductSet ps = (ProductSet) supplement.getSupplementEdition("", "").getEntity(); 116 | logger.info("Helicopter Product Edition Test for 'Default parameters' return code " 117 | + ps.getStatus().getCode().intValue()); 118 | int code = ps.getStatus().getCode().intValue(); 119 | assertEquals(code, 200); 120 | } 121 | 122 | @Test 123 | public void testProductReleseVOLTypo() { 124 | 125 | supplement = new SupplementCharts(); 126 | ProductSet ps = (ProductSet) supplement.getSupplementRelease("", "Typo").getEntity(); 127 | int code = ps.getStatus().getCode().intValue(); 128 | assertEquals(code, 404); 129 | } 130 | 131 | @Test 132 | public void testProductEditionVOLTypo() { 133 | supplement = new SupplementCharts(); 134 | ProductSet ps = (ProductSet) supplement.getSupplementEdition("", "typo").getEntity(); 135 | logger.info("Helicopter Product Edition Test for 'Default parameters' return code " 136 | + ps.getStatus().getCode().intValue()); 137 | int code = ps.getStatus().getCode().intValue(); 138 | assertEquals(code, 404); 139 | } 140 | 141 | @Test 142 | public void testProductReleseEDTypo() { 143 | 144 | supplement = new SupplementCharts(); 145 | ProductSet ps = (ProductSet) supplement.getSupplementRelease("TYPO", "Typo").getEntity(); 146 | int code = ps.getStatus().getCode().intValue(); 147 | assertEquals(code, 400); 148 | } 149 | 150 | @Test 151 | public void testProductEditionEDTypo() { 152 | supplement = new SupplementCharts(); 153 | ProductSet ps = (ProductSet) supplement.getSupplementEdition("TYPO", "typo").getEntity(); 154 | logger.info("Helicopter Product Edition Test for 'Default parameters' return code " 155 | + ps.getStatus().getCode().intValue()); 156 | int code = ps.getStatus().getCode().intValue(); 157 | assertEquals(code, 400); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/main/java/gov/faa/ait/apra/api/DailyDigitalObstacleFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Federal Aviation Administration (FAA) public work 3 | * 4 | * As a work of the United States Government, this project is in the 5 | * public domain within the United States. Additionally, we waive copyright 6 | * and related rights in the work worldwide 7 | * through the Creative Commons 0 (CC0) 1.0 Universal public domain dedication 8 | * 9 | * APRA is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | */ 14 | package gov.faa.ait.apra.api; 15 | 16 | import static gov.faa.ait.apra.bootstrap.ErrorCodes.ERROR_400; 17 | import static gov.faa.ait.apra.bootstrap.ErrorCodes.ERROR_404; 18 | import static gov.faa.ait.apra.bootstrap.ErrorCodes.ERROR_500; 19 | import static gov.faa.ait.apra.bootstrap.ErrorCodes.RESPONSE_200; 20 | 21 | import java.net.MalformedURLException; 22 | import java.net.URL; 23 | import java.text.SimpleDateFormat; 24 | import java.util.Date; 25 | 26 | import javax.ws.rs.GET; 27 | import javax.ws.rs.Path; 28 | import javax.ws.rs.Produces; 29 | import javax.ws.rs.core.MediaType; 30 | import javax.ws.rs.core.Response; 31 | 32 | import org.slf4j.Logger; 33 | import org.slf4j.LoggerFactory; 34 | 35 | import gov.faa.ait.apra.bootstrap.Config; 36 | import gov.faa.ait.apra.cycle.ChartCycleElementsJson; 37 | import gov.faa.ait.apra.jaxb.ChangeCodeList; 38 | import gov.faa.ait.apra.jaxb.EditionCodeList; 39 | import gov.faa.ait.apra.jaxb.FormatCodeList; 40 | import gov.faa.ait.apra.jaxb.ObjectFactory; 41 | import gov.faa.ait.apra.jaxb.ProductCodeList; 42 | import gov.faa.ait.apra.jaxb.ProductSet; 43 | import gov.faa.ait.apra.jaxb.ProductSet.Edition; 44 | import io.swagger.annotations.Api; 45 | import io.swagger.annotations.ApiOperation; 46 | import io.swagger.annotations.ApiResponse; 47 | import io.swagger.annotations.ApiResponses; 48 | 49 | @Path("/ddof") 50 | @Api(value="Daily Digital Obstacle File (DDOF)") 51 | 52 | /** 53 | * This service provides the Daily Digital Obstacle File (DDOF) download link and edition information. There is only one release at any given time and it is the 54 | * daily DOF data file. 55 | * @author FAA 56 | * 57 | */ 58 | public class DailyDigitalObstacleFile extends BaseService { 59 | private static final Logger logger = LoggerFactory.getLogger(DailyDigitalObstacleFile.class); 60 | 61 | /** 62 | * This is the base chart download URL. A single parameter is provided to retrieve the URL for the current day's edition 63 | * @return 64 | */ 65 | @GET 66 | @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) 67 | @Path("/chart") 68 | @ApiOperation(value="Get Daily Digital Obstacle File download link.", 69 | notes="The Daily Digital Obstacle File release is distributed as a zip file containing the latest obstacle information from the FAA database.", 70 | response=ProductSet.class) 71 | @ApiResponses(value = { 72 | @ApiResponse(code = 200, message = RESPONSE_200), 73 | @ApiResponse(code = 400, message = ERROR_400), 74 | @ApiResponse(code = 404, message = ERROR_404), 75 | @ApiResponse(code = 500, message = ERROR_500)}) 76 | 77 | public Response getDDOFRelease () { 78 | 79 | logger.info("Received call to retrieve current DDOF product release for edition."); 80 | setFormat(ZIP); 81 | ProductSet ps = getRelease(); 82 | return Response.status(ps.getStatus().getCode()).entity(ps).build(); 83 | 84 | } 85 | 86 | /** 87 | * This is the base chart download URL. A single parameter is provided to retrieve the URL for the current day's edition 88 | * @return 89 | */ 90 | @GET 91 | @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) 92 | @Path("/info") 93 | @ApiOperation(value="Get Daily Digital Obstacle File edition information.", 94 | notes="The Daily Digital Obstacle File is released by the FAA on a daily basis.", 95 | response=ProductSet.class) 96 | @ApiResponses(value = { 97 | @ApiResponse(code = 200, message = RESPONSE_200), 98 | @ApiResponse(code = 400, message = ERROR_400), 99 | @ApiResponse(code = 404, message = ERROR_404), 100 | @ApiResponse(code = 500, message = ERROR_500)}) 101 | 102 | public Response getDDOFEdition () { 103 | 104 | logger.info("Received call to retrieve current DDOF edition information."); 105 | setFormat("ZIP"); 106 | ProductSet response = initPositiveResponse(); 107 | ProductSet.Edition ed = initEdition(null); 108 | response.getEdition().add(ed); 109 | 110 | ed = initEdition(null); 111 | response.getEdition().add(ed); 112 | 113 | return Response.status(response.getStatus().getCode()).entity(response).build(); 114 | 115 | } 116 | 117 | private ProductSet getRelease() { 118 | return buildResponse(null); 119 | } 120 | 121 | // http://tod.faa.gov/tod/DOF_DAILY_CHANGE_UPDATE.ZIP 122 | 123 | @Override 124 | protected ProductSet buildResponse(ChartCycleElementsJson cycle) { 125 | ProductSet response = initPositiveResponse(); 126 | 127 | addProduct(Config.getDDOFFile(), response); 128 | addProduct(Config.getDDOFDailyChangeFile(), response); 129 | 130 | return response; 131 | } 132 | 133 | private void addProduct (String name, ProductSet ps) { 134 | StringBuilder downloadURL = new StringBuilder(); 135 | ProductSet.Edition ed = initEdition(null); 136 | Edition.Product product = new Edition.Product(); 137 | product.setProductName(ProductCodeList.DDOF); 138 | product.setChange(ChangeCodeList.CHANGED); 139 | downloadURL.append(Config.getDDOFHost()).append(Config.getDDOFPath()).append("/").append(name); 140 | try { 141 | product.setChartName(name); 142 | URL url = new URL (downloadURL.toString()); 143 | product.setUrl(url.toString()); 144 | } 145 | catch (MalformedURLException emalformed) { 146 | logger.warn("The DDOF download URL is not valid", emalformed); 147 | product.setUrl(""); 148 | } 149 | ed.setProduct(product); 150 | ps.getEdition().add(ed); 151 | 152 | return; 153 | } 154 | 155 | @Override 156 | protected Edition initEdition (ChartCycleElementsJson cycle) { 157 | Date today = new Date (System.currentTimeMillis()); 158 | ObjectFactory of = new ObjectFactory(); 159 | 160 | ProductSet.Edition ed = of.createProductSetEdition(); 161 | 162 | SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); 163 | ed.setEditionDate(formatter.format(today)); 164 | ed.setEditionNumber(1); 165 | ed.setEditionName(EditionCodeList.DAILY); 166 | ed.setFormat(FormatCodeList.fromValue(getFormat())); 167 | ed.setGeoname("US"); 168 | 169 | return ed; 170 | } 171 | 172 | } 173 | --------------------------------------------------------------------------------