diff --git a/.env b/.env index 97887ac..842cf89 100644 --- a/.env +++ b/.env @@ -1,2 +1,2 @@ PUBLIC_URL=. -PORT=3002 \ No newline at end of file +PORT=3002 diff --git a/README.md b/README.md index cde142d..ccba729 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,108 @@ Visualizations of coverage and performance analysis for Community Cellular Netwo Now hosted on https://coverage.seattlecommunitynetwork.org/ -# Testing & Deployment + +## Initial Setup +To install this service, the fist time, you will need to: + +1. Required tools and versions: + 1. Install `node` and `npm` according to the directions at https://nodejs.org/en/download/package-manager + 2. Install `pm2` using: `npm install pm2 -g` (as per https://www.npmjs.com/package/pm2#installing-pm2) +2. Clone the service: `https://github.com/Local-Connectivity-Lab/ccn-coverage-vis` +2. Configure: + 1. `cd cd ccn-coverage-vis` + 1. Edit `src/utils/config.ts` and set the correct URL for your API host (if you're testing or you're deploying to a new URL). +4. Deploy as below. +5. When starting the ccn-coverage-vis service the first time, use: + ``` + pm2 start --name "Vis Server" npm -- run start + ``` + This will register ccn-coverage-vis with [PM2](https://pm2.keymetrics.io/docs/usage/quick-start/). + + +## Deploying +Once the service has been setup (as above), it can be deployed using the following process: +1. Login to the coverage-host +2. Pull the lastest version from github +3. Restart the service + +The shell commands are: +``` +ssh coverage-host +cd ccn-coverage-vis +git pull +npm install +npm run build +pm2 restart Vis Server +``` + +## Troubleshooting & Recovery +When a problem occurs, there are several checks to determine where the failure is: +1. Check HTTP errors in the browser +1. Login to the coverage-host +2. Confirm ccn-coverage-vis is operating as expected +3. Confirm nginx is operating as expected + +### Checking HTTP errors in the browser +First, open your browser and go to: https://coverage.seattlecommunitynetwork.org/ + +Is it working? + +If not, open up the browser **Web Developer Tools**, usually under the menu Tools > Developer Tools > Web Developer Tools. + +With this panel open at the bottom of the screen select the **Network** tab and refresh the browser page. + +Look in the first column, Status: +* `200`: OK, everything is good. +* `502`: Error with the backend services (behind nginx) +* `500` errors: problem with nxginx. Look in `/var/log/nginx/error.log` for details. +* `400` errors: problem with the service. Check the service logs and nginx logs. +* Timeout or unreachable error: Something is broken in the network between your web browser and the coverage-vis host. + + +### Checking ccn-coverage-vis with pm2 +Next, confirm ccn-coverage-vis is operating as expected. To do this, you will need to be able to log into the server hosting the coverage service. + +Use `pm2 list` to confirm the "Vis Server" is **online** +``` +ssh coverage-host +pm2 list +``` +![Online services under PM2](pm2-running-services.png "Online services under PM2") + +If the "Vis Server" is not online as expected, restart it with: +``` +pm2 restart Vis Server +``` + + +### Checking nginx +If there appear problems with nginx, then check that the + +Check service operation: +``` +systemctl status nginx +``` + +Check nginx logs: +``` +sudo tail /var/log/nginx/error.log +``` + +Sources of errors might include nginx configuration in `/etc/nginx/conf.d/01-ccn-coverage.conf` + +If you need to restart nginx, use: +``` +sudo systemctl restart nginx +``` + +### Clean Recovery +If nothing else works, the last option is a clean reinstall of the service. The process is: +* Remove the `ccn-coverage-vis` directory. +* Re-install as per **Initial Setup**. + + +## Testing Changes to the main branch are automically built and deployed to: https://seattlecommunitynetwork.org/ccn-coverage-vis/ diff --git a/package.json b/package.json index 79723c8..ee25fd8 100644 --- a/package.json +++ b/package.json @@ -44,8 +44,8 @@ "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", - "format": "prettier --write --config ./prettierrc.json 'src/**/*.{ts,tsx}'", - "format-check": "prettier --check --config ./prettierrc.json 'src/**/*.{ts,tsx}'" + "format": "prettier --write --config ./prettierrc.json src/**/*.{ts,tsx}", + "format-check": "prettier --check --config ./prettierrc.json src/**/*.{ts,tsx}" }, "eslintConfig": { "extends": [ diff --git a/pm2-running-services.png b/pm2-running-services.png new file mode 100644 index 0000000..7ff8f50 Binary files /dev/null and b/pm2-running-services.png differ diff --git a/src/vis/MeasurementMap.tsx b/src/vis/MeasurementMap.tsx index 40866f1..ed821a4 100644 --- a/src/vis/MeasurementMap.tsx +++ b/src/vis/MeasurementMap.tsx @@ -1,22 +1,22 @@ -import React, { useEffect, useState } from 'react'; -import { MapType } from './MapSelectionRadio'; -import { API_URL } from '../utils/config'; -import { SCRAPER_URL } from '../utils/config'; -import * as L from 'leaflet'; -import * as d3 from 'd3'; -import * as parser from 'parse-address'; +import React, { useEffect, useState } from "react"; +import { MapType } from "./MapSelectionRadio"; +import { API_URL } from "../utils/config"; +import { SCRAPER_URL } from "../utils/config"; +import * as L from "leaflet"; +import * as d3 from "d3"; +import * as parser from "parse-address"; import { siteMarker, siteSmallMarker, isSiteArray, -} from '../leaflet-component/site-marker'; -import getBounds from '../utils/get-bounds'; -import MapLegend from './MapLegend'; -import fetchToJson from '../utils/fetch-to-json'; -import Loading from '../Loading'; -import axios from 'axios'; -import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch'; -import 'leaflet-geosearch/dist/geosearch.css'; +} from "../leaflet-component/site-marker"; +import getBounds from "../utils/get-bounds"; +import MapLegend from "./MapLegend"; +import fetchToJson from "../utils/fetch-to-json"; +import Loading from "../Loading"; +import axios from "axios"; +import { GeoSearchControl, OpenStreetMapProvider } from "leaflet-geosearch"; +import "leaflet-geosearch/dist/geosearch.css"; // Updated with details from: https://stadiamaps.com/stamen/onboarding/migrate/ const ATTRIBUTION = @@ -26,7 +26,7 @@ const ATTRIBUTION = '© OpenStreetMap contributors'; const URL = `https://tiles.stadiamaps.com/tiles/stamen_toner_lite/{z}/{x}/{y}${ - devicePixelRatio > 1 ? '@2x' : '' + devicePixelRatio > 1 ? "@2x" : "" }.png`; const BIN_SIZE_SHIFT = 0; @@ -34,7 +34,7 @@ const DEFAULT_ZOOM = 10; const LEGEND_WIDTH = 25; function cts(p: Cell): string { - return p.x + ',' + p.y; + return p.x + "," + p.y; } // print results of user search event to console @@ -43,7 +43,7 @@ function searchEventHandler(result: any): void { console.log(result); var addressLabel = result.location.label; console.log(addressLabel); - // var parser = require("parse-address"); + // var parser = require("parse-address"); var parsedAddr = parser.parseLocation(addressLabel); console.log("hello 1"); console.log(parsedAddr); @@ -65,48 +65,81 @@ function searchEventHandler(result: any): void { var postcode = result.location.raw.address.postcode; var state = result.location.raw.address.state; - var url = SCRAPER_URL // server "http://127.0.0.1:8000/" - + "?state=" + state - + "&cityname=" + city - + "&primary=" + parsedAddr.number - + "&street_number=" + parsedAddr.street - + "&st=" + parsedAddr.type - + "&post_direction=" + post_direction - + "&zip_5=" + postcode; - //+ "&zip_9=" + "3207"; + var url = + SCRAPER_URL + // server "http://127.0.0.1:8000/" + "?state=" + + state + + "&cityname=" + + city + + "&primary=" + + parsedAddr.number + + "&street_number=" + + parsedAddr.street + + "&st=" + + parsedAddr.type + + "&post_direction=" + + post_direction + + "&zip_5=" + + postcode; + //+ "&zip_9=" + "3207"; console.log(url); - const xhr = new XMLHttpRequest(); //xhr.open('GET', "http://127.0.0.1:8000/?state=va&cityname=arlington&primary=3109&street_number=9th&st=St&post_direction=N&zip_5=22201&zip_9=2024"); - xhr.open('GET', url); - xhr.onload = function() { - console.log("200 check"); - console.log(xhr.status); - if (xhr.status === 200) { - //result.marker.setPopupContent(xhr.responseText); - result.marker.setPopupContent(organizePopup(xhr.responseText, postcode, lon, lat)); - } + xhr.open("GET", url); + xhr.onload = function () { + console.log("200 check"); + console.log(xhr.status); + if (xhr.status === 200) { + //result.marker.setPopupContent(xhr.responseText); + result.marker.setPopupContent( + organizePopup(xhr.responseText, postcode, lon, lat) + ); + } }; xhr.send(); } - - // organize popup content. called from searchEvenHandler -function organizePopup(apiText: any, postcode: any, lon: any, lat: any): string{ +function organizePopup( + apiText: any, + postcode: any, + lon: any, + lat: any +): string { let dict = JSON.parse(apiText); console.log(dict); - if(Object.keys(dict).length == 0) { - return "No prices could be found." + "Visit " + "FCC National Broadband Map." + " to see providers in your area, and " - + "allconnect.com" + " to see provider rates in your area."; + if (Object.keys(dict).length === 0) { + return ( + "No prices could be found." + + "Visit " + + "FCC National Broadband Map." + + " to see providers in your area, and " + + "allconnect.com" + + " to see provider rates in your area." + ); } - let returnString = "
" + "Provider" + " | " - + "" + "Speeds" + " | " - + "" + "Rate" + " | " - + "
---|
" + + "Provider" + + " | " + + "" + + "Speeds" + + " | " + + "" + + "Rate" + + " | " + + "
---|---|---|
" + keyName + " | " - + "" + dict[key]["Available speeds"] + " | " - + "" + dict[key]["Starting at"] + " | " - + "
" + + keyName + + " | " + + "" + + dict[key]["Available speeds"] + + " | " + + "" + + dict[key]["Starting at"] + + " | " + + "
"+ "Disclaimer: The table above shows a general estimate of the rates and providers in your area, using information from these sources: "
- + "
" + "allconnect.com"
- + "
" + "FCC National Broadband Map."
- + "
" +
+ "Disclaimer: The table above shows a general estimate of the rates and providers in your area, using information from these sources: " +
+ "
" +
+ "allconnect.com" +
+ "
" +
+ "FCC National Broadband Map." +
+ "