public class Random {
public byte[] generate(int length) {
...
}
}
public class SecureRandom extends Random {
public byte[] generate(int length) {
...
}
}
public class StringProcessor {
private final StringReader stringReader;
private final StringWriter stringWriter;
public StringProcessor(StringReader stringReader,
StringWriter stringWriter) {
this.stringReader = stringReader;
this.stringWriter = stringWriter;
}
public void printString() {
stringWriter.write(stringReader.getValue());
}
}
public int cntEvn(Collection<int> cln) {
int cnt = 0;
for(int i : cln) {
if(i % 2 == 0) {
cnt++;
}
}
return cnt;
}
public int countEvenItems(Collection<int> collection) {
int evenItems = 0;
for(int i : collection) {
if(item % 2 == 0) {
evenItems++;
}
}
return evenItems;
}
public void countThings(Collection<int> things) {
...
}
public void numerateThings(Collection<int> things) {
...
}
(Go) Migrate
mongodb-migrations
Maven (Java):
src/main/resources/db/migration/V1/V1.0__Create_Table_users.sql
CREATE TABLE users (
id bigint(20) NOT NULL AUTO_INCREMENT,
username varchar(100) NOT NULL,
first_name varchar(50) NOT NULL,
last_name varchar(50) DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY UK_username (username)
) DEFAULT CHARSET=utf8;
src/main/resources/db/migration/V1/V1.1__Create_Table_admins.sql src/main/resources/db/migration/V2/V2.0__Create_Table_things.sql
Add column, n versions later remove old column.
function reticulateSplines(){
// current implementation lives here
}
function reticulateSplines(){
var useNewAlgorithm = false;
// useNewAlgorithm = true; // UNCOMMENT IF YOU ARE WORKING
// ON THE NEW SR ALGORITHM
if( useNewAlgorithm ){
return enhancedSplineReticulation();
}else{
return oldFashionedSplineReticulation();
}
}
function oldFashionedSplineReticulation(){
// current implementation lives here
}
function enhancedSplineReticulation(){
// TODO: implement better SR algorithm
}
Push state to the boundaries (Databases)
public class GoogleSearch {
static WebDriver driver = new FirefoxDriver();
static Wait<WebDriver> wait = new WebDriverWait(driver, MAX_30_SECONDS);
public static void main(String[] args) {
boolean result;
driver.get("http://www.google.com/");
try {
result = firstPageContainsQAANet();
} catch(Exception e) {
result = false;
} finally {
driver.close();
}
System.out.println("Test " + (result? "passed." : "failed."));
}
private static boolean firstPageContainsQAANet() {
//type search query
driver.findElement(By.name("q")).sendKeys("qa automation\n");
// click search
driver.findElement(By.name("btnG")).click();
// Wait for search to complete
wait.until(webDriver -> {
System.out.println("Searching ...");
return webDriver.findElement(By.id("resultStats")) != null;
});
// Look for QAAutomation.net in the results
return driver.findElement(By.tagName("body")).getText().contains("qaautomation.net");
}
}
@Test
public class SomeKeyGoogleService {
public SearchServiceConnection searchService;
@Before
public void init() {
// Initialize service
searchService = ...;
}
@After
public void clean() {
// Do some cleaning
}
@Describe("Given Youtube service has results and there are existing indexed pages " +
"When a phrase searched Then return Youtube with indexed results")
public void usuallyThisWillBeAMeaningfullName() {
// given
youtubeMock.when("/searchResults?search=my%20search%20phrase")
.thenReturn("{video: \"http://youtube.com/v?asd123@!ASd2134=\"}");
db.insert(new IndexedPage("Welcome to my search phrase"));
// when
var returnContent = searchService.call("/search?s=my%20search%20phrase").result().asJson();
// then
expect(returnContent).toConsistOf(youtubeVideo("http://youtube.com/v?asd123@!ASd2134="),
pageInfo("Welcome to my search phrase"));
}
}
public class AlertAdderTest
{
public SlackAlertAdder slackAlertAdder = mock(SlackAlertAdder.class);
public FacebookAlertAdder facebookAlertAdder = mock(FacebookAlertAdder.class);
public AlertAdder alertAdder = new AlertAdder(slackAlertAdder, facebookAlertAdder);
@Test
public void whatAnAlertIsAddedThenSlackAlertIsAdded()
{
Alert anAlert = new Info("Holy shit, watch out");
alertAdder.add(anAlert);
verify(slackAlertAdder).add(anAlert);
}
}
Produce -> Collect -> Index -> Use
Service-wise
Fluentd/ Logstash
Elasticsearch
Kibana
Also: Correlation Ids, Schema
Using correlation Ids we can create a flow of the data:
Counter counter = Counter
.builder("instance")
.description("indicates instance count of the object")
.tags("dev", "performance")
.register(registry);
counter.increment(2.0);
assertTrue(counter.count() == 2);
counter.increment(-1);
assertTrue(counter.count() == 2);
SimpleMeterRegistry registry = new SimpleMeterRegistry();
Timer timer = registry.timer("app.event");
timer.record(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1500);
} catch (InterruptedException ignored) { }
});
timer.record(3000, MILLISECONDS);
assertTrue(2 == timer.count());
assertTrue(4510 > timer.totalTime(MILLISECONDS)
&& 4500 <= timer.totalTime(MILLISECONDS));
Business Metrics
A Key Performance Indicator (KPI)
Mean time to failure (MTTF)
Mean Time to Repair (MTTR)
pipeline {
agent any
tools {
maven 'Maven 3.3.9'
jdk 'jdk8'
}
stages {
stage ('Initialize') {
steps {
sh '''
echo "PATH = ${PATH}"
echo "M2_HOME = ${M2_HOME}"
'''
}
}
stage ('Build') {
steps {
sh 'mvn -Dmaven.test.failure.ignore=true install'
}
post {
success {
junit 'target/surefire-reports/**/*.xml'
}
}
}
}
}
version: 2
jobs:
build:
docker:
- image: circleci/<language>:<version TAG>
steps:
- checkout
- run: echo "hello world"
deploy:
docker:
- image: java:8-jre-alpine
steps:
- run: java -jar my-app-*.jar
FROM alpine/git
WORKDIR /app
RUN git clone https://github.com/spring-projects/spring-petclinic.git
FROM maven:3.5-jdk-8-alpine
WORKDIR /app
COPY --from=0 /app/spring-petclinic /app
RUN mvn install
FROM openjdk:8-jre-alpine
WORKDIR /app
COPY --from=1 /app/target/spring-petclinic-1.5.1.jar /app
CMD ["java -jar spring-petclinic-1.5.1.jar"]
Single application as a suite of small services.
Service is built around business capabilities and independently deploy-able.
Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.
-- Melvyn Conway, 1967
Build a simple solution, put it in front of customers, enhance incrementally based on customer feedback.