Engineering: HTTP and SSL
- REST - Representational State Transfer (read below).
- HTTP - Hypertext Transfer Protocol - often equated with REST. The basis for the World Wide Web typified by Request/Response Objects, Headers, Parameters, HTTP Methods, and Sessions.
- SSL - TLS - HTTPS - Hypertext Transfer Protocol with Security.
Certificates
- Certificate Authority - validates a Certificate (say,
X.509). - Public and Private Keys - a kind of Symmetric Encryption that bifurcates Credentials into two pieces.
REST
REST (Representational State Transfer) - a client-server architectural paradigm that encourages the following core precepts:
- Client-Server - the familiar Client to Server paradigm. A Client connects to a Server.
- Statelessness - user Session data isn't stored or persisted between Sessions.
- Layered System - read Service Layer Architecture article.
- Uniform Interface - common data types, HTTP Methods, etc.
Methods:
- OPTIONS - indicates that a Client is seeking a Server and further HTTP Request information (required HTTP Headers, etc.).
- GET - indicates that a Client will READ a persisted resource.
- POST - indicates that a Client will CREATE a persisted resource.
- PUT - indicates that a Client will UPDATE a persisted resource.
- PATCH - indicates that a Client partially UPDATE a persisted resource.
- DELETE - indicates that a Client intends to DELETE a persisted resource.
Request / Response Lifecycle
The HTTP Request/Response Lifecycle:
- Request Object -
- Headers - specifies the
Content-Type, CORS information, Credentials or Tokens, etc. (sent back from the Web Client). - HTTP Method - OPTIONS, GET, POST, PUT, PATCH, DELETE .
- URL (Uniform Resource Locater) - the IP Address with optional Port number, DNS address, etc.
- Parameters (optional) - specify query filters to narrow down some query result:
id,page, etc. - Body (optional) - submitted or requested information can be regimented as JSON, text, a form, etc., and encapsulated by the Request and Response Objects.
- Headers - specifies the
- Response Object -
- Headers - specifies the
Content-Type, CORS information, Credentials or Tokens, etc. of the Response Object (sent back from the Web Server). - Body (optional) - submitted or requested information can be regimented as JSON, text, a form, etc., and encapsulated by the Request and Response Objects.
- Headers - specifies the
OData
OData defines many of the familiar items above (and more). Some key topics:
- Unique identifiers for Objects/Items to be accessed by.
- Uniform Resource Locators
- ISO/IEC 20802-2:2016 specifies JSON Format (which got rolled into OData).
- Common HTTP Headers
- Recommending different URL for READ and WRITE -type operations (REST Uniform Interface).
OData is nearly synonymous with REST (which is itself nearly synonymous with HTTP) in practice.
Engineering: TCP, UDP, IP, DNS
- IP - Internet Protocol Address
- IPv6
- Hexadecimal
- 128-Bit IP Address
- Eight groups of four hexadecimal digits
- Example:
2031:0ca7:75×3:13f3:0103:8b1e:0310:7532
- IPv4
- Purely numeric (decimal)
- 32-Bit IP Address
- Four octets in the inclusive range
0-255 - Example:
127.0.0.1
- CIDR - Classless Inter-Domain Routing
- Solution for allocating IP Addresses and IP Routing.
- The convention
<MY_IP_ADDRESS>/<CIDR_LENGTH>(e.g. -10.0.0.0/16) specifies the CIDR Length for the IP Address (Prefix). - The CIDR Length defines the number of bits reserved for the Netmask.
- The Netmask divides an IP Address into sections akin to dividing a Zip Code into Street Addresses.
- Used to specify which part of the Host IP Address space is reserved for the Host number and which is reserved the Subnet number.
- The lower the CIDR Length, the more IP Addresses are available within the network.
- Classes and their respective Netmasks:
- Class A -
255.0.0.0 - Class B -
255.255.0.0 - Class C -
255.255.255.0
- Class A -
(From: https://erikberg.com/notes/networks.html)CIDR Notation Host Formula Available Hosts /8232-8 - 216,777,214/9232-9 - 28,388,606/10232-10 - 24,194,302/11232-11 - 22,097,150/12232-12 - 21,048,574/13232-13 - 2524,286/14232-14 - 2262,142/15232-15 - 2131,070/16232-16 - 265,534/17232-17 - 232,766/18232-18 - 216,382/19232-19 - 28,190/20232-20 - 24,094/21232-21 - 22,046/22232-22 - 21,022/23232-23 - 2510/24232-24 - 2254/25232-25 - 2126/26232-26 - 262/27232-27 - 230/28232-28 - 214/29232-29 - 26/30232-30 - 22
- IPv6
- DNS - Domain Name Service - associates a (purely) numeric IP Address (
127.0.0.1) with a human readable/friendly Domain Name (localhost). - TCP - Transmission Control Protocol - a Transport Layer protocol that complements IP (TCP/IP). Is used to negotiate and determine connections themselves prior to data being transmitted.
- UDP - User Datagram Protocol - responsible for actually sending packets and messages over TCP/IP. One-directional, requires some other system to actually manage the connections themselves. (Although it can be used without establishing or verifying connections.)
- HTTP/2 - introduces Huffman Encoding to compress packet sizes when initially negotiating an HTTP Request.
- QUIC - HTTP/3 - built on top of UDP and removes TCP as the Transport Layer and optimizes some of the initial handshaking resulting in reduced packet sizes, I/O, etc. Multiplexed, persistent connection.
- A Proxy is used as an intermediary between an IP Address and a destination resource.
- Note: Proxying typically refers to Forward Proxying.
- Forward Proxying (a Forward Proxy Server) is connected to by a Client in order to mask the Client IP Address. The Forward Proxy then connects to a desired resource. (The Proxy masks the incoming IP Address and uses the desired outgoing IP Address.)
- A Reverse Proxy is a hidden Gateway or intermediary between the Client and desired resource. (AWS API Gateway is paradigmatic - a Client makes an HTTP Request to a specific endpoint; the endpoint is associated with a configured Lambda Function which is called on behalf of the inbound Request.)
- Forward Proxying is deliberately used or known to the Client. By contrast, in Reverse Proxying scenarios the Proxy acts unbeknownst to the Client.
- Note that both kinds of Proxying involve the same sequential pattern: a Client
Cconnects to an intermediary ProxyPto access a desired target resourceR.
- An SSH Bastion serves as an intermediary between an incoming SSH connection and a desired resource.
- The SSH Bastion serves to "jump" the incoming SSH connection to the desired resource after the inbound connection is authenticated and authorized.
- In this way, destination resources are protected from being exposed publically and all inbound SSH requests can be verified/controlled.
Resources and Links
- https://cybermeteoroid.com/ipv4-vs-ipv6-differences-you-need-to-know/
- https://www.geeksforgeeks.org/what-is-ipv6/
- https://quicwg.org/
- https://www.rfc-editor.org/rfc/rfc4632.html
- https://stackoverflow.com/questions/46616072/cidr-blocks-aws-explanation
- https://www.rfc-editor.org/info/rfc1918
- https://erikberg.com/notes/networks.html
- https://docs.oracle.com/cd/E19455-01/806-0916/ipconfig-32/index.html
- https://stackoverflow.com/questions/224664/whats-the-difference-between-a-proxy-server-and-a-reverse-proxy-server
- https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#forwardreverse
Engineering: Open Systems Interconnection
Open Systems Interconnection (OSI) summary.
OSI Layers
Each OSI Layer
- Physical Layer
- Physical Devices (Network Switches, Ethernet Hub, Controllers).
- Physical transmission and serialization of raw data.
- Data Link Layer
- Transference of Data over the Physical Layer.
- Example protocols:
802.3 Ethernetand802.11 Wi-Fi.
- Network Layer
- Includes: TCP/IP (Transmission Control Protocol, Internet Protocol).
- Packet Forwarding.
- Internet Addressing.
- Transport Layer
- Data Packets and transferrence of Data from sender to destination.
- TCP and User Datagram Protocol (UDP).
- Also, QUIC which runs on UDP (without TCP).
- Session Layer
- The actual Connections (HTTP or otherwise) between Devices, Computers.
- Any User- or Client Connection- specific Setting, Configuration.
- User Authorization and Authentication info.
- Presentation Layer
- Data Formatting (JSON, XML, Unicode, ASCII).
- Data Compression, Encryption/Decryption.
- Application Layer
- REST, HTTP, SMTP, FTP, etc.
- Standards or Specifications that pertain to Applications and their intercommunication.
Resources and Links
Engineering: Status Codes
200- Status OK: OK.201- Created successfully typically via POST: Created.202- Queued, batched successfully but not complete: Accepted.301- URL permanently moved400- Bad request - malformed: Bad Request401- Unauthorized, lacking credentials: Unauthorized.403- Forbidden, no authorization to access even with credentials: Forbidden.404- Page or resource can't be found at specified URL: Page Not Found.405- Wrong HTTP method supplied.500- Internal Server Error.502- When a server acting as a gateway (or proxy) receives an invalid response from an upstream server or resource: Bad Gateway.503- When a server is not ready (or available due to being overloaded or maintenance) to handle a request: Service Unavailable.504- When a server acting as a gateway (or proxy) doesn't get a response in time from an upstream server or resource: Gateway Timeout.
Engineering: Common Port Numbers
443- HTTPS/TLS default port number8080- HTTP/URL default port number22- SSH default port number25- SMTP default port number1433- MSSQL default port number
Note:
80/443are usually the default port numbers used by gRPC since it uses HTTP/S - for example as in this article I wrote: https://goteleport.com/docs/api/getting-started/
Engineering: Logging Levels
Logging levels.
Common and Log4j
Some subset of the following is likely to be encountered in most logging frameworks (Log4j) or tools (Terraform).
In descending order of visibility:
TRACE- Most granular, used to gain trace information throughout the entirety of an Application (including third-party dependencies).DEBUG- Used primarily when debugging or inDevelopmentto detail the innerworkings of written code.INFO- Most granular visibility used inProduction.WARN- Something unusual or unexpected but less than an outright Exception or Application terminating event.ERROR- An Exception, planned for or unexpected.FATAL- An Application terminating event.
Of the above:
INFO,WARN, andERRORare the three primary logging levels that most teams will default to.
Java Util
java.util.logging.Level differs from the above by using (in descending order):
SEVEREWARNINGINFOCONFIGFINEFINERFINEST
https://docs.oracle.com/javase/8/docs/api/java/util/logging/Level.html
Resources and Links
Engineering: Naming Conventions
Some common naming conventions:
- Dry - database naming convention -
Persontable with aPersonClass domain Object Relational Mapping (ORM) - Snake Case -
some_person - Camel Case -
somePerson - Pascal -
Person
Engineering: Basic Terminal Commands
Shebang
Specifies where to find and which bash executable to use as the execution environment.
On modern Linux systems it's recommended to use:
#!/usr/bin/env bash
Consult: https://tldp.org/LDP/abs/html/sha-bang.html and https://stackoverflow.com/questions/10376206/what-is-the-preferred-bash-shebang
Nano and Vim
Edit a file in Bash:
nano filename
Edit (enable Insert or Interactive Mode) from within the editor:
i
# toggle Insert or Interactive Mode - click i to enable
esc
# toggle Insert or Interactive Mode - exit
Save and exit editor:
:wq!
Exit editor without saving:
:q!
:qa
https://tecadmin.net/save-and-quit-vim/ and https://vim.rtorr.com/
Save Output of Command to File
# stdout and file
MY_COMMAND | tee output.txt
# append to file but don't print to stdout
MY_COMMAND >> output.txt
# overwrite file but don't print to stdout
MY_COMMAND > output.txt
Kill Task
Taskkill /IM node.exe /F
killall node
Open SSL
openssl genrsa -out key.pem 2048
openssl req -new -sha256 -key key.pem -out csr.csr
openssl req -x509 -sha256 -days 365 -key key.pem -in csr.csr -out certificate.pem
Grant Permission
Grant (all) Read, Write, and modify permissions:
sudo chmod +rwx file
Check permissions:
ls -l
Check CPU and Hyper-V Settings
Windows cmd:
systeminfo
SSH Keys
Generate a new SSH Public and Private Key pair using ssh-keygen:
ssh-keygen -t ed25519 -C "your_email@example.com"
Open the Public Key (with suffix .pub) and copy the Public Key into the necessary cloud resource account (GitHub, etc.).
Copy the Private Key into ~/.ssh (or equivalent) and associate with ssh-agent:
ssh-add ~/.ssh/id_ed25519
SSH Key mappings will be visible in /.ssh/known_hosts.
An excellent resource: https://docs.github.com/en/authentication/connecting-to-github-with-ssh
Mac: View Hidden Files
Hold-down: Command + Shift + Period (⌘⇧.) simultaneously to see hidden (system) files.
Mac: Multiple DB Browser for SQLite Clients
To open multiple instances of DB Browser for SQLite at the same time:
"/Applications/DB Browser for SQLite.app/Contents/MacOS/DB Browser for SQLite" &
Visual Studio Code
- Hold
crtl++andcrtl+-simultaneously to zoom in or out.
IP Address
Useful Linux DNS, IP Address, Port, Connection, Name Server, Host, Record, Route Table tools:
dig
nslookup
host
ping
netstat
whois
ipinfo
nslookup,dig, andhostare very similar and perform the same functionalities.
Resources and Links
- https://tldp.org/LDP/abs/html/sha-bang.html
- https://stackoverflow.com/questions/10376206/what-is-the-preferred-bash-shebang
- https://tecadmin.net/save-and-quit-vim/
- https://vim.rtorr.com/
- https://docs.github.com/en/authentication/connecting-to-github-with-ssh
- https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
- https://sqlitebrowser.org/
Code samples:
Engineering: Mac Install Notes
Personal notes to get a development environment setup and configured on macOS 10.15.3.
Note: configuring
.bash_profileis required for macOS-specific directory paths.
Note: configuring
.bashrcis required for many Bash-specific paths.
Note: configuring
.zshrcis required for many Zsh-specific paths (macOS Catalina+).
The notes below are written for Bash. In most cases, the same commands and export statements can be used interchangeably between Bash and Zsh (provided you use the correct configuration file).
I'm also not a huge fan of Homebrew (think Catalina system directory structure incompatibility, multiple lingering installs, version conflicts that typically or eventually arise locally, etc.) so the installation steps below tend to prefer the native installers wherever possible and appropriate.
Xcode
For developing Apple mobile, desktop, tablet, and watch, applications.
Swift installation:
- Use this link: https://apps.apple.com/us/app/xcode/id497799835 to get Swift + Xcode
- Test the installation using
$ swift --version - Test the Xcode installation using
$ xcodebuild -version
CocoaPods:
- Requires Ruby gem manager
- Execute the following:
$ sudo gem install cocoapods - Use
$ pod installto download the dependencies into your project - NOTE: You must open the
<PROJECT_NAME>.xcworkspacefile rather than the<PROJECT_NAME>.xcodeprojfile to build and compile your project (with Pods) correctly
Python 2.7
For Python, PIP, and Django apps.
Python 2.7 installation:
- Python 2.7 is pre-installed on macOS 10.x.
- Test the installation using
$ python --version
PIP installation:
- Execute
$ sudo easy_install pip - Test the installation using
$ pip --version
Django installation:
- Execute
$ sudo pip install Django==3.0.3 - Alternatively, execute
$ sudo pip install -r requirements.txt
Python 3
For Python 3.x.
Python 3.x installation:
- Download from: https://www.python.org/downloads/mac-osx/
- Test the installation using
$ python3 --version
PIP:
- PIP is automatically installed as part of the Python 3 installation
- Upgrade PIP:
$ python3 -m pip install --upgrade pip - Install dependencies:
$ python3 -m pip install -r requirements.txt - List all installed libraries:
$ pip freeze - Clear out PIP cache:
$ pip uninstall -y -r <(pip freeze)
Venv:
- Venv is automatically installed as part of the Python 3 installation
- Create a Venv environment:
$ python3 -m venv VENV_ENV - ... and activate it:
$ source VENV_ENV/Scripts/activate
Ruby
For Ruby on Rails apps.
Ruby installation:
- Ruby 2.6.3p62 is pre-installed on macOS 10.x.
- Test the installation using
$ ruby --version - Test Ruby gem manager using
$ gem -v
Rails installation:
$ gem install rails
C++
- C++ GCC 4.2.1 is distributed with Xcode 11.3 (whose installation instructions are provided above).
- Test the installation using
$ gcc --version
CMake:
- Download the CMake Unix/Linux Source (has \n line feeds) from: https://cmake.org/download/
- Extract the contents and execute
$ bash bootstrapwithin the root directory - Then execute
$ cd Bootstrap.cmkand$ bash make - Copy the following into
.bash_profileusing$ sudo nano ~/.bash_profile(and modify as needed):
export PATH=$PATH:/Users/USER_NAME/Desktop/cmake-3.16.6/bin
- Test the installation:
$ cmake --version
Java
For Java Spring, Gradle, Maven, and Tomcat stacks.
Java installation:
- Use this link: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
- Test the installation using
$ javac -version
Apache Tomcat 8.5.x installation:
- Download the
.zipfrom http://tomcat.apache.org - Copy the extracted directory to your desktop (or some other appropriate location)
- Navigate to the
ROOT/bindirectory and execute the following Bash commandsudo chmod +x *.sh - Execute
$ sudo bash startup.shto launch Tomcat on the default portlocalhost:8080
Refer to the very helpful: https://wolfpaulus.com/tomcat/ for more comprehensive configurations.
Gradle installation:
- Download from: https://gradle.org/install/
- Copy the following into
.bash_profileusing$ sudo nano ~/.bash_profile(and modify as needed):
export PATH=$PATH:/Users/USER_NAME/Desktop/gradle-6.2/bin/
- Test the installation using
$ gradle --version
Node
For NodeJS server and client apps.
NVM installation:
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.1/install.sh | bash$ sudo touch ~/.bash_profile$ sudo touch ~/.bashrc$ sudo nano ~/.bash_profile- copy the contents below into this file$ sudo nano ~/.bashrc- copy the contents below into this file
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
(Copy the above into configuration files.)
- Test the installation using
$ nvm ls - Download the desired version of Node using
$ nvm install 10.0.0 && nvm use 10.0.0
Typescript installation:
- Execute
npm install -g typescript
Golang
- Go to: https://golang.org/dl/ and download the newest version
- Install Go using the downloaded installer
- Test the installation using
$ go version
Rust
For Rust apps.
Rust installation:
- Execute
$ sudo curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh - Test the installation using
$ rustc --version
Rust uninstallation:
$ rustup self uninstall
Refer to the Rust documentation.
Disable DS_Store Files
Open Terminal App:
Located in Applications > Utilities
Enter the following command:
defaults write com.apple.desktopservices DSDontWriteNetworkStores true
Brew
As of macOS 14.4.1 (23E224) you may need to install Homebrew for certain commonly used dependencies:
Download Homebrew or by running:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"Run the commands:
(echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/YOUR_USERNAME/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)"to add Homebrew to
PATH.Note that
.zprofileis the default shell config from the official documentation.Run
source .zprofile(orsource .bash_profile) to reload the relevant terminal configsTo install
pkg-configon Mac:brew install pkg-config(required for Python3)
zsh
Duplicate any .bash_profile entries into .zprofile (or .zshrc):
.zprofileis for login shells.zshrcis for interactive shells
WinRAR on Mac
- Add:
PATH="/Users/username/Desktop/rar:${PATH}"to~.zprofile. - Given password
@ZeGV
# Will delete files and encrypt
rar a -df -p@ZeGV -r _data.rar ./_data
# No leading ./ in _data
## Special chars like ! don't appear to be allowed here
rar x -p@ZeGV _data.rar _data
The Official Command Line Syntax documentation.
Resources and Links
- https://apps.apple.com/us/app/xcode/id497799835
- https://doc.rust-lang.org/stable/
- https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
- https://www.techrepublic.com/article/how-to-disable-the-creation-of-dsstore-files-for-mac-users-folders
- https://unix.stackexchange.com/questions/71253/what-should-shouldnt-go-in-zshenv-zshrc-zlogin-zprofile-zlogout
- https://documentation.help/WinRAR/HELPCommandLineSyntax.htm
Engineering: Windows Install Notes
It's been a while since I used a Windows machine for development. (Windows has traditionally been my preferred and most commonly encountered development environment of choice.) Have to say, I'm immensely impressed by Windows 11!
There are many great changes overall (and, I disagree with some critics - the new taskbar is much improved - centering the icons is a much better experience than having to peer over in the left corner on large screens/UHD 4K TVs).
Node
This will install
Node,Git, andPython 2.7.
As of 5/21/2022 - Windows 11 Pro
21H222000.675.
For Node:
Make sure to open your terminal of choice with the
Run As Administratoroption (equivalent in some ways tosudo).Rename the
pythonexecutable to topython2(node-gyprequires this nomenclature).Search locally for
sysdm.cplto open System Properties -> Advanced -> Environmental Variables in Windows 11.Add the install path to your
UserandSystem Variables.nvm install X.Y.Z && nvm use X.Y.Z(in Bash or ZSH) for the specific version ofNodeyou want.I've had the best luck using
Visual Studio 2017 (Community)rather than a newer version. Download after signing into Microsoft here.Make sure to tick off:
C# and Visual Basic Rosyln compilersMSBuildStatic analysis toolsVisual Studio C++ core featuresWindows 10 SDK (10.0.17763.0)
Run
npm config set msvs_version 2017Run
npm ior whatevernpmornodecommands you desire.
Java
This will install
Java 1.18,Maven,Tomcat 10andGradle.
Updated 8/25/2022 - Windows 11 Pro
21H222000.856.
- Download Java 1.18
- Download Maven 3.8.6
- Download Tomcat 10
- Download Gradle 7.5.1
- Add the relevant System variables under Advanced system settings > Environment Variables.
GRADLE_HOMEshould point at your unzipped Gradle root directory.JAVA_HOMEshould point to your Java root directory.MAVEN_HOMEshould point to your unzipped Maven root directory.- Then add the following to your Path.
%JAVA_HOME%\bin,%GRADLE_HOME%\bin%MAVEN_HOME%\bin
Run the folloiwng commands to verify your installs.
javac -versionmvn -versiongradle --version
Navigate to: http://localhost:8080/ after running the new(ish) Apache Tomcat10 executable.
Engineering: Azure VM Ubuntu 18.04
Brief setup notes for Azure VM Ubuntu 18.04 on Mac OSx.
- Create Public and Private Keys
Create a private key. A public key will be created automatically for you.
ssh-keygen -t rsa
Make note of your private key password - this is used to authenticate below.
After creating your Azure Ubuntu 18.04 VM. Take note of your Public IP.
Ensure that the default SSH port is left open.
- Connect from Local Machine
sudo ssh -i path/private_key user@public_ip
Use your private key password after connecting.
Ubuntu 18.04 VM
Slightly different setup than Ubuntu 14.04.
sudo apt-get update
sudo apt-get upgrade
Git
sudo apt-get update
sudo apt install git
Node
sudo apt install nodejs
sudo apt install npm
Java
Note: It's recommended to download Java 11+ directly from Oracle.
It's further recommended to use the OpenJDK 11.0.2 (and avoid other options).
Refer to: https://jdk.java.net/archive/
sudo apt-get update
wget "https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz"
sudo tar -xzvf openjdk-11.0.2_linux-x64_bin.tar.gz
sudo mv jdk-11.0.2 /usr/lib/jvm/
# Config
sudo nano /etc/environment
# Add the line below
# JAVA_HOME="/usr/lib/jvm/jdk-11.0.2/"
# Config
sudo nano ~/.bashrc
# Add the lines below
# JAVA_HOME=/usr/lib/jvm/jdk-11.0.2/
# PATH=$JAVA_HOME/bin:$PATH
source ~/.bashrc
# Verify
echo $JAVA_HOME
javac --version
Tomcat:
groupadd tomcat
useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat
cd /opt/
sudo wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.2/bin/apache-tomcat-9.0.2.tar.gz
tar -xzvf apache-tomcat-9.0.2.tar.gz
sudo mv apache-tomcat-9.0.2 tomcat
Then:
# Permissions
sudo chown -hR tomcat:tomcat tomcat
sudo chmod +xr tomcat/bin/
# Config
sudo nano ~/.bashrc
# Add the line below
# CATALINA_HOME=/opt/tomcat
# Config
source ~/.bashrc
# Verify
echo $CATALINA_HOME
You can now access /opt/tomcat/bin/ to execute: sudo bash startup.sh.
Your Tomcat server will be available by default on http://YOUR_IP:8080 (note the lack of https here).
Engineering: Misc
Commonly encountered and useful topics.
HTML Escape Characters
Can use the following in many places where typical spaces/whitespace isn't allowed (will often force a Whitespace to appear):
Resources and Links
Engineering: OWASP
Summary of common top 10 OWASP identified security vulnerabilities:
- Broken Access Control
- Violation of The Principle of Least Privilege
- Privilege elevation
- CORS misconfiguration
- Insecure direct object references
- Metadata manipulation
- Cryptographic Failures
- Weak, old, or deprecated cryptographic algorithms
- Lack of encryption: TLS, etc.
- Low randomness used: pseudorandom, improper seed
- Injection
- SQL Injection
- Query Injection
- Lacking character escaping, validation, filtering, or sanitization
- Ability for users to execute queries from a client input
- Insecure Design
- Ability of malicious actors to exploit weaknesses in system design, architecture, or business logic
- Example: not restricting the number of tickets a person can buy, not having rate limiting, etc.
- Security Misconfiguration
- Leaving Ports open
- Insufficient security hardening
- A system whose dependencies aren't updated
- Disabled security features
- Incompatible dependency versions
- Vulnerable and Outdated Components
- Deprecated, out-of-date, or old software and/or dependencies
- Lacking a critical security patch
- Identification and Authentication Failures
- Lacks multi-factor authentication
- Allows for weak passwords
- Transmission of passwords in plaintext
- Susceptibility to automated or brute-forcing attacks
- Software and Data Integrity Failures
- Downloading unsigned dependencies from a remote repository
- Downloading dependencies from an untrusted remote repository
- A compromised update
- Insecure deserialization
- Security Logging and Monitoring Failures
- Exposing critical or sensitive data within accessible logs
- Unclear or unhelpful logging messages
- Lacking proper logging for critical events
- Lacking the proper visibility into critical events, services, or systems
- Lacking appropriate mechanisms to remediate problems: escalation, on-call rotations, etc.
- Server-Side Request Forgery
- Improperly allowing a web application and/or its resources to be accessed or controlled remotely
- Allowing an unauthenticated, unvalidated, or unauthorized agent to access a resource remotely
Resources and Links
Engineering: Application Security
A concise, quick, overview.
SOC2
- Every completed task must be documented.
- Every customer-facing or production task must have a corresponding ticket.
OWASP
- Available here: https://owasp.org/www-project-top-ten/
- Common Security Vulnerabilities include XSS, SQL Injection, String Timing attackes, etc.
Encrypt at Rest
- Encrypt database information within the database.
- Never store sensitive PII information in plaintext.
Ports
- Verify that all unneeded Ports are closed.
Secure Access Workstation
- Increasingly popular.
- An air-gapped physical machine allowing access to a single user at a single precise time.
- The air-gapped physical machine then connects to an SSH Bastion.
Engineering: OAuth 2.0
Grant Types
The four main Authorization Grant Types are as follows (note that the PKCE extension is now recommended for supplemental use in all other Grant Types):
Authorization Code
The flow:
- A resource R1 requests access to a protected resource R2.
- A user (who typically owns or manages both resources) is directed to an intermediary authentication server to authorize R1’s getting R2’s data (for some duration of time).
- After authorizing access, the user is redirected to a specified URL (often a view in R1): the Redirect URL.
- The most common and secure Grant Type. Use this by default.
- The paradigm or model OAuth flow that inspired the others.
Client Credentials
- Used in server-to-server access where one resource is able to access a second (common in micro-services).
Device Code
- Where a device with limited human input capabilities is granted access to a resource through another human input medium.
- Used to give IoT devices access to some endpoint. These devices may lack a keyboard.
Refresh
- Used to refresh a previously acquired valid token.
Deprecated
Note that the Password and Implicit Grant Types are now deprecated:
Password
- Deprecated.
- Essentially, your standard user-submitted password to get a token authentication scheme.
Implicit
- Deprecated.
- Often used in minimal security conditions (like a simple JavaScript app) to acquire a token from an auth server through a (registered) Client ID.
- Tokens are not refreshed but simply reacquired.
Resources and Links
Engineering: Service Layer Architecture
- Presentation Layer - what the user sees and interacts with. A web Client, mobile device, terminal, etc. Corresponds to the View in MVC pattern.
- Service Layer - contains Business Logic, Controllers, Handlers, and Services that process Data being sent from a Client, and that return processed Data to the Client.
- Data Layer - persisted Data that exists at rest or used in-memory.
Engineering: Model View Controller
- Model - programmatic representations of Data defined in a Domain. Run Time, in-memory, and programmatic representations of persisted data that may or may not be managed 1:1 through an Object Relational Mapping framework like Hibernate.
- View - what's rendered and presented to the user.
- Controller - HTTP REST Controllers, Handlers that reside at sepecifc Endpoints (e.g. - URL, URL Path, IP Address, Domain Name, Port Number) etc. to handle specific HTTP Requests / HTTP Methods.
Engineering: Design Patterns
Some common design patterns.
Singleton
Refer to the other Singleton article.
Factory
The Factory design pattern creates copies of a specific type. The Factory itself is usually instantiated once, often a Singleton (single instance object).
// Java
public class Dood {
//...
}
public Dood doodFactory() {
//...
getDooder() {
return new Dood();
}
}
Abstract Factory
Suppose that
Kis a subclass ofT: make a Factory of kindTthat returns a Factory or makes Objects of kindK(through abstract implementation.
The Abstract Factory design pattern is essentially the Factory design pattern but involves Abstract Factories in correspondence with and supporting an abstract (here, meaning higher-order) interface implementation hierarchy or abstract class hierarchy:
First, a (higher-order) interface:
// Java
public interface A {
//...
}
Two implementations of that interface:
// Java
public class B implements A {
//...
}
public class C implements A {
//...
}
Now, we create a factory hierarchy to parallel the implementation hierarchy:
// Java
public interface AbstractFactory {
public A createA();
}
We then create two further factories concrete implementations of AbstractFactory*`:
// Java
public class BFactory implements AbstractFactory {
public A createA() {
B b = new B();
return b;
}
}
public class CFactory implements AbstractFactory {
public A createA() {
C c = new C();
return c;
}
}
Model View Controller
Refer to the other Model View Controller article.
Decorator
Uses annotations like @Component to configure some item or add functionality.
Examples:
- Angular
- Java Spring
- Java EE
Adapter
The Adapter pattern takes two incompatible implementations, Interfaces, or Classes, and provides a way to bridge them. (Hence, "Adapter" - to adapt them to each other.)
// Java
public interface GermanPlugConnector {
public void giveElectricity();
}
public class GermanElectricalSocket {
public void plugIn(GermanPlugConnector plug) {
plug.giveElectricity();
}
}
// Java
public interface UKPlugConnector {
public void provideElectricity();
}
public class UKElectricalSocket {
public void plugIn(UKPlugConnector plug) {
plug.provideElectricity();
}
}
These are thus far incompatible and require an Adapter to bring them into harmony:
// Java
public class GermanConnectorToUKSocketAdapter implements UKPlugConnector {
private GermanPlugConnector plug;
public GermanConnectorToUKSocketAdapter(GermanPlugConnector plug) {
this.plug = plug;
}
@Override
public void provideElectricity() {
plug.giveElectricity();
}
}
Above we implemented the compatible Plug connector (UKPlugConnector) but overrode provideElectricity() so that it now invokes giveElectricity() on the incompatible Plug connector (GermanPlugConnector).
We have thus performed a little "switch-a-roo" on the main point of incompatibility by using a third interface to bring the two incompatible types into harmony thereby.
Now we explicitly invoke our adapter to representationally allow the GermanPlugConnector to plug into the UKElectricalSocket:
// Java
GermanPlugConnector plugConnector = //.. create a GermanPlugConnector
//Create a UKElectricalSocket
UKElectricalSocket electricalSocket = new UKElectricalSocket();
//We adapt the two
UKPlugConnector ukAdapter = new GermanConnectorToUKSocket(plugConnector);
//And now receive the electricity
electricalSocket.plugIn(ukAdapter);
Example corrected, updated, and modified from: http://www.vogella.com/tutorials/DesignPatternAdapter/article.html
Retry, Backoff, and Circuit Breaker
Some or all of the following can and usually should be combined to correctly handle Errors at the Enterprise Web Application / Service level:
| Strategy | Description | Advanced |
|---|---|---|
| Retry | Attempts again. | Dead Letter Queue, Maximum Number of Attempts |
| Exponential Backoff | Time interval between attempts increases each try. | Maximum Number of Attempts |
| Circuit Breaker | Functionalitites are disabled. | Status Flow, Blast Radius, Service/Functionalities Flows |
- Retry
- An essential Design Pattern that involves retrying an operation when an
Exception, failure, or fault is encountered. - Typically combined with Exponential Backoff strategies that increase the interval of time between each retry attempt. (Otherwise an
Exceptioncan result in the "Stampeding Herd" (cascading failure) phenomenon and a single failure can become many.) - Often combined with a predetermined maximum number of attempts (after which subsequent events are handled by and delegated to a Dead Letter Queue).
- An essential Design Pattern that involves retrying an operation when an
- Circuit Breaker
- An
Exception, failure, fault, or specified condition "trips" or triggers disables or blocks additional calls or functionalities from occuring. - Events move through predefined status conditions with associated cooldown time intervals. As event statuses change, functionalities are enabled, disabled, or slowed.
- An
Quick and helpful overview of these topics.
Resources and Links
Engineering: The Twelve-Factor App
Summary of Twelve-Factor App Principles:
- Codebase - One codebase tracked in revision control, many deploys.
- A single codebase is used for an App.
- E.g. - a specific repo in GitLab, BitBucker, Subversions, Azure Team Foundation, or GitHub.
- Use a versioning system to track different deployments and changes.
- Use a version control tool like Git or Subversion.
- A single codebase is used for an App.
- Dependencies - Explicitly declare and isolate dependencies.
- All dependencies are explicitly and expressly declared in a manifest.
- Examples:
package.json,pom.xml,requirements.txt, etc. - Use a package manager.
- Dependencies should be versioned and modularized so their exact contents can be specified.
- Config - Store config in the environment.
- App Configuration is kept with the App.
- It should be stored as Environmental Variables within the Environment itself.
- Example: passing Docker parameters that are exposed as Environmental Variables within an App Container.
- App Configuration should be grouped by (Staging) Environment.
- Backing Services - Treat backing services as attached resources
- Any Service or infrastructure dependency is treated as a Resource that's attached (containerized or configured along with the Service in question).
- Examples:
docker-compose.yml, Terraform, Cloud Formation
- Build, Release, Run - Strictly separate build and run stages.
- Separate a deployment into Build, Release, and Run stages.
- All Releases should have a unique identifier.
- Processes - Execute the app as one or more stateless processes.
- Apps should be run as Processes.
- They should be Stateless.
- Example: containerizing and App in a Docker Container that spins up and initializations the App state each time it's run (state isn't preserved).
- Port Binding - Export services via port binding.
- Preference for directly binding an App to a Port via a Webserver library (Jetty).
- As opposed to using a Web Container (Tomcat).
- Concurrency - Scale out via the process model.
- While one may need to spawn or multithread, these processes should use established tools and infrastructure to do so (Node
exec, JVM Threads, Windows Process management). - Don't create/spawn Daemons when the above can be used out of the box.
- While one may need to spawn or multithread, these processes should use established tools and infrastructure to do so (Node
- Disposability - Maximize robustness with fast startup and graceful shutdown.
- Processes should be easy to terminate.
- Deployed Services shouldn't be unnecessarily dependent on or entangled with other systems. They should be sufficiently decoupled so that they can started and stopped easily.
- Dev/Prod Parity - Keep development, staging, and production as similar as possible.
- (Staging) Environments should be 1:1.
- Logs - Treat logs as event streams.
- All logging events are printed to
STDOUTand never routed within the app. - All log organization is handled at the Enivronment level.
- Example:
- Set Logging Levels within an AWS Environment so that it can be collated into a log ingestion Service.
- Rather than routing logs using distinct say, Log4J
LoggingAppenders.
- All logging events are printed to
- Admin Processes - Run admin/management tasks as one-off processes.
- They should have a finite execution interval (should not be ongoing or occasion indefinite access to say PROD).
- They should always use the most up-to-date config and code (not ad-hoc scripts or old code versions).
Resources and Links
Engineering: Producers and Consumers
- Consumer - The resource that consumes, receives, and/or uses Messages or Events sent by the Producer.
- Producer - The emitter or sender of a Message or Event to the Consumer
Publish Subscribe and Message Queues
Several commonly encountered patterns that involve Producer and Consumer topics:
- Publish-Subscribe
- Subscribers listen to, wait for, poll, or otherwise directly subscribe to a Publisher (specifically, a Publisher's Topics) which emits an Event or Message to all appropriate Subscribers.
- Examples:
- AWS Simple Notification Service (AWS SNS)
- Apache Kafka
- WebSockets
- Message Queue
- A Message Queue sits in-between a Producer and Consumer. Often explicitly uses an intermediary called (or appropriately likened to) a Message Broker.
- Examples:
- ActiveMQ
- RabbitMQ
- AWS Simple Queue Service (AWS SQS)
- SOAP
- A Consumer requests a WSDL from the Producer to mirror the Domain entities of a Producer (generates the shared contract for the Consumer).
- This allows SOAP requests to be correctly made from the Consumer to the Producer and for the Consumer to correctly handle the corresponding SOAP responses.
- REST
- A Client (Consumer) makes an HTTP Request to a Server (Producer) which returns an HTTP Response.
Note that this distinction isn't strictly mutually exclusive. While Quastor refers to RabbitMQ as thoroughly Pub-Sub, the actual RabbitMQ documentation refers to it as Publish/Subscribe (since it can be configured as such).
Resources and Links
- https://blog.quastor.org/p/tech-dive-apache-kafka
- https://www.rabbitmq.com/tutorials/tutorial-three-spring-amqp
Code samples:
Engineering: Systems Design
Topics
- Separation of Concerns - Access, Visibility, proper decomposition of a Monolithic app, database access, subnets, private networks
- Concurrency - Thread, Thread and Worker Pooling, database Connection Pooling, use of Mutex and Thread-Safety, Asynchronous and Non-Blocking, Load Balancing, Sharding
- Events, Messaging, and Event Priority - use of Cron Jobs, Queues, Event Scheduling, Event Workflows
- Fault Tolerance - High Availability and Disaster Recovery, ProdEng manual overrides, data auditing and integrity, Graceful and Exponential Backoff, Dead Letter and Retry Queues
- Performance - Caching, Views and Indexes, Algorithm optimization, Elasticity, duplex connections
- Best Practices - Security, compliance, Integration Testing and environments, End to End Acceptance Tests, etc.
Some Approaches
Some common, famous, and or high-performance approaches:
- Decouple Events, Consumers, and Producers - Apache Kafka remains a top choice at many firms (PayPal, Uber, Dosh, etc.).
- A move from Relational Databases to Document Store Databases reducing overhead from Sharding, need for Cross-Database JOINS, SQL Table Normalization, and IO/latency.
- Modifying SQL Table Columns is very expensive on large datasets that are distributed over many Shards.
- Extensive use of Sharding, Consistent Hashing (keeps Hash invariant as number of Shards increases), and Load Balancing across different Application Layers.
- Lots of Caching:
- Clear distinction between READ and WRITE intensive resources (and corresponding resource responsibilities - READ Replica, etc.).
- Materialized Views, etc.
- Extensive use of Memcached, Redis, and/or Couchbase for READ intensive operations.