-
Ember.js notes
install ember
npm install -g ember-cli
new project
ember new devops-dashboard cd devops-dashboard ember serve
new route
ember generate route projects # update index template application.hbs --}} <h1>DevOps Dashboard</h1> # update project.hbs: <h2>projects</h2> <ul> <li></li> </ul> # update projects.js to provide modeling: import Route from '@ember/routing/route'; export default Route.extend({ model() { return ['java-project-A', 'python-project-B', 'emberjs-project-C']; } });
now we get a /projects page contains a list of projects.
setup default route
now I want to set the /projects as the index:
# vi routes/index.js import Route from '@ember/routing/route'; // https://guides.emberjs.com/release/routing/redirection/#toc_transitioning-before-the-model-is-known export default Route.extend({ beforeModel(/* transition */) { this.transitionTo('projects'); // Implicitly aborts the on-going transition. } });
fetch data from http as modeling
# use github/python projects as modeling # projects.js import Route from '@ember/routing/route'; export default Route.extend({ model() { // return ['java-project-A', 'python-project-B', 'emberjs-project-C']; return $.getJSON("https://api.github.com/orgs/python/repos"); } }); # show project names in projects.hbs <h2>projects</h2> <ul> <li></li> </ul>
now our app lists all projects belongs to github/python.
create sub-route for project details
ember generate route projects/view # add link from projects to proejct/view # projects.hbs <h2>projects</h2> <ul> <li> </li> </ul> # route.js to accpet parameter from link Router.map(function() { this.route('projects', function() { this.route('view', {path: '/:id'}); }); }); # view.js to collect parameters import Route from '@ember/routing/route'; export default Route.extend({ model(params) { // Ember.Logger.log("params: " + params.id); return params.id; } }); # view.hbs to display <h3>current project: </h3>
stop rendering parents outlet
Each template will be rendered into the of its parent route’s template. https://guides.emberjs.com/release/routing/rendering-a-template/
we don’t really need to display the projects list in
projects/view
, so: https://stackoverflow.com/questions/32160056/ember-how-not-to-render-parents-templateember generate route projects/index // migrate code from projects.js/projects.hbs to projects/index.js(.hbs)
add bootstrap
ember install ember-bootstrap // then restart ember server
add static file
mkdir public/assets vi public/assets/data/projects.json // use in js: // return $.getJSON("https://api.github.com/orgs/python/repos"); return $.getJSON("/assets/data/projects.json");
-
Installing and configuring Java/Maven environment in Mac
Java
installing jdk
download and install jdk from: http://www.oracle.com/technetwork/java/javase/downloads/index.html
mutiple JDK can be installed: e.g. java 1.8 and java 10.
check installed jdk
run
man java_home
to know how:The java_home command returns a path suitable for setting the JAVA_HOME environment variable. It determines this path from the user’s enabled and preferred JVMs in the Java Preferences application. Additional constraints may be provided to filter the list of JVMs available. By default, if no constraints match the available list of JVMs, the default order is used. The path is printed to standard output.
bash-3.2$ /usr/libexec/java_home -V Matching Java Virtual Machines (2): 10.0.2, x86_64: "Java SE 10.0.2" /Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home 1.8.0_45, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home bash-3.2$ /usr/libexec/java_home -v 1.8 --exec java -version java version "1.8.0_45" Java(TM) SE Runtime Environment (build 1.8.0_45-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode) bash-3.2$ /usr/libexec/java_home -v 10 --exec jshell | Welcome to JShell -- Version 10.0.2 | For an introduction type: /help intro jshell> /exit | Goodbye bash-3.2$ export JAVA_HOME=`/usr/libexec/java_home -v 1.8` bash-3.2$ java -version java version "1.8.0_45" Java(TM) SE Runtime Environment (build 1.8.0_45-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
config java_home
according to
man java_home
: set java_home in~/.bash_profile
:export JAVA_HOME=`/usr/libexec/java_home`
check with java is in use actaully
ls -al /usr/bin/java
removing java
cd /Library/Java/JavaVirtualMachines sudo rm -rf jdk-10.0.2.jdk # verify /usr/libexec/java_home -V
Maven
installing / configuring maven
download and unzip maven, then set m2_home in
~/.bash_profile
:export M2_HOME=$tools/current-maven export PATH=$M2_HOME/bin:$PATH
check maven settup
mvn -v
will print the maven home and java home. if java home is incorrect, verify your environment details with your$M2_HOME/bin/mvn
. -
What I Learned from a Performance Testing
I recently joined a new team as a do-everything engineer. The team is working hard to push a newly web app to production. the app enables existing users buy products which are provides by an external vendor. the app relies on existing authentication services, payment services, order services, etc.
After spending couple weeks with an existing ‘Performance testing’ team, I finally get the test ‘approved’. I learned couple things from this process.
if a downstream service is not available for testing, mock it.
or else the performance test won’t happen at all. given the following diagram, it’s almost impossible to get all dependencies ready for my testing, e.g:
- UserService has a testing envrionment, but it took days to request a test user.
- PaymentGateway requires UserInfo ready and all test data will be created manually — an account could run out of money in the middle of a performance test.
agreed with core stockholders, I performed the test with:
the app itself + mocked (existing) internal services + real external services.
+-----+ +-----------------------+ +-------------+ +-------------------------+ +-----------------------+ +-----------------+ +-----------------------+ | App | | AuthenticationService | | UserService | | ExternalProductService | | InternalOrderService | | PaymentGateway | | ExternalOrderService | +-----+ +-----------------------+ +-------------+ +-------------------------+ +-----------------------+ +-----------------+ +-----------------------+ | | | | | | | | | | | | | | | | | | | | | | user login | | | | | | |----------------------->| | | | | | | | | | | | | | | user info verify request | | | | | | |-------------------------------->| | | | | | | | | | | | | | verified | | | | | | |<--------------------------------| | | | | | | | | | | | | tokens | | | | | | |<-----------------------| | | | | | | | | | | | | | get user info | | | | | | |--------------------------------------------------------->| | | | | | | | | | | | | | user info | | | | | |<---------------------------------------------------------| | | | | | | | | | | | | fetch products | | | | | | |------------------------------------------------------------------------------->| | | | | | | | | | | | | | products | | | | |<-------------------------------------------------------------------------------| | | | | | | | | | | | user place order | | | | | | |---------------------------------------------------------------------------------------------------------->| | | | | | | | | | | | | | | verify toke / payment request | | | | | | |--------------------------------------->| | | | | | | | | | | | | | payment processed | | | | | | |<---------------------------------------| | | | | | | | | | | | | | place order | | | | | | |-------------------------------------------------------------->| | | | | | | | | | | | | | order confirmation | | | | | |<--------------------------------------------------------------| | | | | | | | | | | | order confirmation | | | |<----------------------------------------------------------------------------------------------------------| | | | | | | | | |
Performance testing should be conducted from Day 1
during the performance testing, one slowness issue was detected: it took quite long time to get users info from the mocked UserService. the mocked UserService does very straightforward job: returning a fixed user info form a local server. so it’s not caused by UserServie / network, the issue must be caused the app itself. I reviewed the sourcecode, an unnecessary synchronization was applied to the servlet. it was added in the first commit half year ago, the feedback loop for this piece of code is: 6 months.
if we run PT as part of the DevOps pipeline, this issue could be identified and fixed in the fist PT.
define / review the performance requirements with stockholders as early as possible
System designing should consider performance requirements. designing a web app for 20 internal users could be very different from designing a web app for 2000 clients. performance concerns should be highlighted earlier, such as external services, proxy servers. if developers are aware that the app need to support 20 concurrent users, probably they will not simply add a
synchronized
to a serverlet.Performance testing should be automated
it took me couple days to help the performance testing team understanding the app, then they spend couple days to prepare their test cases. and if there’s any change to the app. I need to go through the whole process with them again. this does not make sense to me: as an agile team, we’re moving fast, but if it took couple days(even weeks) to test, the test result is not valid since the test finished — more changes already applied to the app. same as other tests, performance test should be automated. it should be executed by a machine, the test should be able to tell that it’s passed or not automatically.
-
NewbornLog 新生儿日志
孕期
Feb 01, 2017 青岛流亭机场
年后返城.
Feb 02, 2017 East Coast Clinic & Surgery For Women
第一次去诊所, 医生兴奋的对着屏幕给我们比划宝宝的位置, 第一次听到宝宝突突突的心跳, 泪眼摩梭, 但我还是没看懂宝宝的位置. 之后每个月都会继续来做产检.
May 22, 2017 NUH
Second Trimester Ultrasound检查, 一切正常.
May 22, 2017 East Coast Clinic & Surgery For Women
确定医院, 跟诊所签package, 此后产检变为每两周一次.
Sept 19, 2017 East Coast Clinic & Surgery For Women
医生担心宝宝过大导致无法顺产, 建议引产. 时间暂定在Sept 26.
第一天
Sept 26, 2017 Parkway East Hospital
早上6点半起床, 小米粥, 七点Uber去医院. 办理手续, 直接进产房. 医生赶来后产检, 破釜沉舟, 刺破羊水, 注射催产素. 医生建议进行无痛麻醉, 两小时后麻醉师将针管插入老婆脊柱. 中午医生再次回来检查, 没有生产迹象, 如果下午5点还没有进展, 建议进行剖腹产. 焦急. 胎心监测仪里的稳定的声音让人心焦. 下午4点半, 医生再次回来, 已经接近9指. 下午5点10分, 宝宝顺利出生. 我激动的说不出话来, 手足无措.
傍晚娘俩被转移到病房, 护士建议每个三个小时让宝宝练习吸奶. 夜里病房里温度很低, 约22度, 空调温度控制也不起作用. 试着把娃留在病房里, 结果哭的不行. 我以为是温度低, 把她推到nursing room, 其实nursing room也是一样的低, 护士说其实温度是适合新生儿的. 回到病房又睡不踏实, 听到哭声就觉得好像是自己的娃在哭, 忍不下又去nursing room把宝宝要回来. 拍一拍她就会再睡一会儿.
胎盘. 老婆说要把胎盘埋到小区里的树下, 所以医生把胎盘包了交给了我. uber回家后拿着一把勺子在树下挖了半天, 掏了一个洞, 把胎盘埋了进去.
第二天
Sept 27, 2017 Parkway East Hospital
还是没奶. 傍晚的时候拖护士加了奶. 夜里照旧把娃留在病房自己带. 开始学着给娃换尿布. 护士留下几瓶奶, 每瓶约45ml, 叮嘱每3个小时喂一次, 一次大约喂35ml. 室温(22度)的瓶装奶打开就直接喂给娃, 她咕叽咕叽的每次都吃完.
医院里配的东南亚风味月子餐实在太难吃, 每天小米粥.
三个月
Dec 26, 2017 SingHealth Polyclinics
8点30, 五合一疫苗. 身高64.5, 体重7.2, 左右大腿各一针. 娃象征性的哭了两声. 中午收到多个未接来电, 打不回去. 中午又跑了一趟: payment搞错了 + 医生忘记给开退烧药. 超过37.5度时喂药水.
下午5点多, 娃开始发烧, 37~37.5. 精神略萎靡, 傍晚去watsons买了退烧贴.
连续三天没有大便.
Dec 27, 2017
大便.
晚上精神很好, 在费雪钢琴上连踢带抓的玩不倒翁.
Dec 28, 2017
早晨体温降到37度内.
对声音不敏感.
Dec 30, 2017
对声音仍旧不敏感. 家人的逻辑让我想到了«水知道答案».
Jan 01, 2018
参加朋友的婚礼注册仪式, 娃放在家里.
朋友的婚礼简单中透着庄重, 他们准备的很认真. 参加别人的婚礼, 对我来说, 是一个回顾及反省的机会. 注册时跟着注册官复读的誓词已经记不清原文, 不管怎样, 都得对对方好吧.
Jan 02, 2018
孩他妈开始上班.
Jan 03, 2018
«水知道答案» 神逻辑.
Jan 07, 2018
第一次理发. 用的是淘宝买来的飞利浦婴儿剃头工具. 家人说小孩头发就是要坑坑洼洼, 我理解的是”狗啃的”. why? 水知道答案.
-
IntelliJ: How to support customized Cucumber feature file extension
Requirement
as a heavy user of Cucumber, I created customized feature file (e.g. .feature2) for my enhancment. I want to add support to customized feature file with IntelliJ and Cucumber plugin.
Solutions
Solution 1: configuring IntellJ
config IntelliJ:
Settings > File Types
, register customized patterns: e.g.*.feature2
Solution 2: customizing cucumber plugin
the IntelliJ Cucumber plugin is created by JetBrains with ‘Apache License 2.0’
so we can download, modify, redistribute it.
before you proceed to downloading, you may want to select the brache with your IntellJ version.
Step 1. Override the
CucumberFileTypeFactory
instead of modifying the original codeCucumberFileTypeFactory
, I prefer to extend it:package aqua; import com.intellij.openapi.fileTypes.ExtensionFileNameMatcher; import com.intellij.openapi.fileTypes.FileTypeConsumer; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.cucumber.psi.CucumberFileTypeFactory; import org.jetbrains.plugins.cucumber.psi.GherkinFileType; public class AquaFileTypeFactory extends CucumberFileTypeFactory{ @Override public void createFileTypes(@NotNull FileTypeConsumer consumer) { consumer.consume(GherkinFileType.INSTANCE, new ExtensionFileNameMatcher("feature"), new ExtensionFileNameMatcher("feature2")); } }
Step 2. Register the
FileTypeFactory
created in Step 1 in `src/META-INF/plugin.xml<idea-plugin version="2"> <id>gherkin</id> <!-- I prefer to keep this id so that other plugins can continue to depend on it --> <name>Gherkin-AQUA</name> <fileTypeFactory implementation="aqua.AquaFileTypeFactory"/> </idea-plugin>
then you may build your plugin redistribute it!
subscribe via RSS