Spring security 4.0.2 ignore csrf url

參考了官方文件: 20.5.2 SockJS & Relaxing CSRF

但是官方底下的XML案例中有些錯誤, 直接貼上是不能跑了, 看了一下source code, 改成可以跑的寫法如下:

...




#{T(org.springframework.security.web.csrf.CsrfFilter).DEFAULT_CSRF_MATCHER}










JBoss BPM Suite 1: 基礎概念

Install

Start up

  • $ cd ../EAP-6.4.0/bin
  • $ ./standalone.sh
  • 登入網址為: http://localhost:8080/business-central
  • 安裝BPM Suite時預設的帳號為 bpmnAdmin (除非在安裝時有特別修改)
  • 變更port:
  • ../EAP-6.4.0/standalone/configuration/standalone.xml
  • <socket-binding name="http" port="8080"/>

概念

Authoring (流程創作)

  • Organizations
  • Repositories
  • Projects
  • Packages

Organizations

Organize workspaces by group or department.

Repositories

All projects and assets are stored in GIT repositories, 一個repository通常代表了一個prcess, 如報價轉保單process

Projects

A project is a collection of all the assets and information needed to build a complete functional system, 包含了process的圖, drl file…等, 但這些東西是存放在其下的package(也就是folders)中的

Packages

All business assets are stored in package folders

基本圖示

為 Object Library, 也就是所有畫圖會用到的物件

為當前目標的 Properties

變數

  • Process變數
  • 可以想像成 Java的class變數
  • 左鍵點選Process中任何一個空白處, 點開 中的Variable Definitions
  • Task變數
  • 可以想像成 Java的method變數
  • 左鍵點選某個Task, 點開 中的DataInputSet, DataOutputSet
  • DataInputSet
  • 類似Java method的input arguments
  • 通常會是從Process變數指向過來
  • DataOutputSet
  • 類似Java method的return 物件
  • 通常會把值指回process變數
  • Assignments, 串起上述所有變數之間的連動

Gateways (菱形的決策點)

只能取得 Process變數來做判斷, 判斷的內容是寫在從 Gateways 連出去的線條上 (並非設定在 Gateways本身的Properties)

Form

可透過BPM Suite自動產生Form


– Process Form (Process被create instance後的輸入畫面)
– Task Form (到這個Task時的輸入畫面)

建立Process順序

建立Organization

  • 主Menu > Authoring > Administration
  • 第二層Menu > Organizational Units > Manage Organizational Units
  • 右方點選Add, 填入name, default group id

建立repository

  • 主Menu > Authoring > Administration
  • 第二層Menu > Repositories > New Repository
  • 輸入name及選擇對應的Organization

建立Project

  • 主Menu > Authoring > Project Authoring
  • 第二層Menu > New Item > Project
  • 輸入name

建立Business Process

  • 主Menu > Authoring > Project Authoring
  • 第二層Menu > New Item > Business Process

Markdown with Atom

曾經用過的Markdown app:

但都不是很順手, 我的需求基本上有幾點:

  1. 完全支援 GitHub Flavored Markdown
  2. Live preview

最近發現, 還是回歸Atom配合Marked 2最順手!

Atom with Markdown Plugins

Markdown Preview Plug

Atom原生就有markdown preview功能, 快速鍵為: control-shift-m

或可以選擇安裝此Plugin (安裝後記得到control-,到package把原生的disable), 官方列出的優點如下:

  • Fastly open a preview of any markdown with ctrl-shift-m
  • Math rendering with persistent macro support, toggled with ctrl-shift-x
  • Optionally use pandoc with citation support
  • Live reload while editing
  • On demand synchronization

Markdown Writer

  • 支援markdown常用的快速鍵, 如: bold(cmd-b), italic(cmd-b), insert image(shift-cmd-i)等
  • 支援draft, post概念
  • Go to Settings (cmd-,) -> Packages -> markdown-writer -> Settings -> Set siteLocalDir and related.
  • 可以直接 Create new post
  • 或Create new draft, 當Publish draft時, 會moves a draft to post’s directory with front matters (date, published) updated.

Export by Marked 2

寫好markdown後, 可以透過 Marked 2 這套app匯出成Github style的html或其他格式

JMeter + Selenium 壓力測試

JMeter環境準備

JMeter透過Run UnitTest來啟動Selenium測試

準備UnitTest Java檔

從Firefox Plugin錄製

直接寫Unit Test

pom.xml

<br />org.seleniumhq.selenium
selenium-java
${selenium.version}

org.seleniumhq.selenium
selenium-firefox-driver
${selenium.version}

org.seleniumhq.selenium
selenium-server
${selenium.version}

java

private WebDriver driver;
private String baseUrl;

@Override
@Before
public void setUp() {
driver = new FirefoxDriver();
baseUrl = "http://localhost:8080/";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}

@Override
@After
public void tearDown() throws Exception {
driver.quit();
}

@Test
public void testLogin() throws Exception {
driver.get(baseUrl);

Assert.assertEquals("Login Page", driver.getTitle());
Assert.assertEquals(baseUrl + "login", driver.getCurrentUrl());

driver.findElement(By.name("username")).clear();
driver.findElement(By.name("username")).sendKeys("admin");
driver.findElement(By.name("password")).clear();
driver.findElement(By.name("password")).sendKeys("admin");
driver.findElement(By.name("submit")).click();

Assert.assertEquals("Demo project for running Selenium scripts with JMeter", driver.getTitle());
Assert.assertEquals(baseUrl, driver.getCurrentUrl());
}

最後將java檔compile後壓成jar檔 (或從Eclipse直接匯出Jar), 放到 %JMETER_HOME%\lib\junit

測試

建立測試計劃

  • Test Plan上, Add > Thread > Thread Group
  • Thread Group上, Add > Sampler > JUnit Request
  • Thread Group上 , Add > Listener > View Result Tree

JUnit Request頁籤中選擇測試的Classname及Test Method

Run Test

  • 從View Result Tree檢視結果

JMeter直接寫WebDriver script

建立測試計劃

  • Test Plan上, Add > Thread > Thread Group
  • Thread Group上, Add > Config Element > FireFox Driver Config
  • Thread Group上, Add > Config Element > Http Cookie Manager
  • Thread Group上, Add > Sampler > WebDriver Sampler
  • Thread Group上 , Add > Listener > View Result Tree

WebDriver Sampler頁籤中寫Script

WDS.sampleResult.sampleStart();
WDS.browser.get('http://localhost:8080/');
WDS.sampleResult.sampleEnd();

if (WDS.browser.getTitle() != 'Login Page') {
WDS.sampleResult.setSuccessful(false);
WDS.sampleResult.setResponseMessage('The title should be "Login Page" at login.jsp');
}

var pkg = JavaImporter(org.openqa.selenium);
WDS.browser.findElement(pkg.By.name('username')).clear();
WDS.browser.findElement(pkg.By.name('username')).sendKeys('admin');
WDS.browser.findElement(pkg.By.name('password')).clear();
WDS.browser.findElement(pkg.By.name('password')).sendKeys('admin');
WDS.browser.findElement(pkg.By.name('submit')).click();

if (WDS.browser.getTitle() != 'Demo project for running Selenium scripts with JMeter') {
WDS.sampleResult.setSuccessful(false);
WDS.sampleResult.setResponseMessage('The title should be "Demo project for running Selenium scripts with JMeter" after login');
}

Run Test

  • 從View Result Tree檢視結果

more to read:

Regux

目標文字:

when
sampleEntity : SampleEntity($code1:code)
sampleEntity2 : SampleEntity2()
if ($code1 == "1" && #max(1, 0) == 1 && #trim("apple ").equals("apple")) do[_1]
else if ($code1 == "2") do[_2]
then

需透過Regular pattern, 取得井字號後面的function name以及input args

原始Pattern #(\w+)\((.+)\)

  • function name正確取得max
  • 但args卻取了整串到: 1, 0) == 1 &amp;&amp; #trim("apple ").equals("apple")
  • 看起來是中間的 . 範圍太大, 導致到最後一個 \)之前都剛成args了

改。Pattern #(\w+)\(([^\)]+)\)

  • 加入了不等於 ^ 的判斷
  • function name正確取得maxstr
  • args也正確抓到了1, 0以及apple
  • 但多了使用限制:input args中不能有close字元
  • #trim(" ) ")就無法接受
    正在思考更好的解決方案…

A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance

Hibernate/JPA在使用到 @OneToMany , 也就是Entity中的關聯是一個 Collection時

當該Object已經在persistent scope中, 一定要避免assign另一個reference到那個 @OneToMany

否則錯誤就會發生

org.hibernate.HibernateException:
A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance:

如:

@JsonManagedReference("process_operation")
@OneToMany(mappedBy = "process", fetch = FetchType.LAZY, cascade = {CascadeType.ALL}, orphanRemoval = true)
private List operations;

不使用setOperations(new ArrayList)

而是 getOperations().clear() 再 getOperations().add()

Transaction with Spring Framework

Support model

  • Global transactions
  • Work with multiple transactional resources
  • Through the JTA, which normally needs to be sourced from JNDI

  • Local transactions

  • Resource-specific (like a JDBC transaction)

PlatformTransactionManager

public interface PlatformTransactionManager {

TransactionStatus getTransaction(
TransactionDefinition definition) throws TransactionException;

void commit(TransactionStatus status) throws TransactionException;

void rollback(TransactionStatus status) throws TransactionException;
}
  • The primarily service provider interface (SPI)
  • Could be easily mocked or stubbed
  • Not tied to a lookup strategy such as JNDI.

常用TransactionManager (程式碼範例: Transaction Strategies)

  • DataSourceTransactionManager (a example with plain JDBC)
  • JtaTransactionManager
  • HibernateTransactionManager (needs a reference to the SessionFactory)

TransactionDefinition specifies

API here

Propagation

Propagation If current transaction exist If current transaction NONE exist
REQUIRED (default) Support the current transaction Create a new one
SUPPORTS Support the current transaction Execute non-transactionally
MANDATORY Support the current transaction Throw an exception
REQUIRES_NEW Create a new one and suspending the current transaction Create a new one
NOT_SUPPORTED Always execute non-transactionally Always execute non-transactionally
NEVER Throw an exception Execute non-transactionally
NESTED Execute within a nested transaction Create a new one

Nested: Only applies to the JDBC DataSourceTransactionManager when working on a JDBC 3.0 driver.
see more @ Transaction propagation

Isolation level:

Isolation Dirty reads Non-repeatable reads Phantom reads
READ_UNCOMMITTED can occur can occur can occur
READ_COMMITTED prevented can occur can occur
REPEATABLE_READ prevented prevented can occur
SERIALIZABLE prevented prevented prevented
DEFAULT Use the default isolation level of the underlying datastore.

Ready-only

This just serves as a hint for the actual transaction subsystem; it will not necessarily cause failure of write access attempts. A transaction manager which cannot interpret the read-only hint will not throw an exception when asked for a read-only transaction.

Declarative transaction management

Roll back is automatic only on unchecked exceptions (Spring default behavior)

<br /><br /><br /><!-- 可以定義除了RuntimeException以外, 哪些Exception也要(或不要)rollback, including checked exceptions. -->



You can also indicate a required rollback programmatically. see more @ Programmatic transaction

public void resolvePosition() {
try {
// some business logic...
} catch (NoProductInStockException ex) {
// trigger rollback programmatically
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}

REQUIRES情境

起始Method (A) 中間Method (B) 例外 結果
Tx Method 任何情況 Commit
Tx Method 任何情況 丟出RuntimeException Rollback all
ReadOnly Tx Method 本支程式另一個Tx Method 兩個Method在同一個ReadOnly Tx中, Commit
ReadOnly Tx Method 另一支程式的Tx Method 延用ReadOnly Tx, Commit

REQUIRES_NEW情境

起始Method (A) 中間Method (B) 例外 結果
Tx Method 本支程式另一個Tx Method 兩個Method在同一個Tx中, Commit
Tx Method 另一支程式的Tx Method B會取得自己的Tx, 兩個Tx都Commit
Tx Method 另一支程式的Tx Method B丟RuntimeException B會取得自己的Tx, 兩個Tx都Rollback
Tx Method 另一支程式的Tx Method A在呼叫B之丟出RuntimeException B不會取得Tx, A Rollback
Tx Method 另一支程式的Tx Method A在呼叫B之丟出RuntimeException B會取得自己的Tx, B Commit, A Rollback
ReadOnly Tx Method 本支程式另一個Tx Method 兩個Method在同一個ReadOnly Tx中, Commit
ReadOnly Tx Method 另一支程式的Tx Method B會產生自己的Tx, 不延用A的ReadOnly Tx, Commit

Aspect-oriented programming

Aspect-oriented programming

Aspect

Regular classes or regular classes annotated with the @Aspect annotation.

<br /><br />...



Join point

Always represents a method execution.

Advice

An interceptor, maintaining a chain of interceptors around the join point.

  • Before advice
  • After returning advice
  • After throwing advice
  • After (finally) advice
  • Around advice
<br /><br /><br /><br />

Pointcut

A predicate that matches join points.

<br /><br /><br />

Supported Designators

Common pointcut definitions:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
throws-pattern?)
  • modifiers-pattern: *, public, private, etc. (Spring AOP only supports advising public methods.)
  • ret-type-pattern: int, long, etc.
  • declaring-type-pattern If the class and advice are in the same package then package name is not required.
  • name-pattern: wildcard supported.
  • param-pattern: Two dots(..) means any number and type of parameters.

Any public method:

execution(public * *(..))

Any method with a name beginning with “set”:

execution(* set*(..))

Any method defined by the AccountService interface:

execution(* com.xyz.service.AccountService.*(..))

Any method defined in the service package:

execution(* com.xyz.service.service.*.*(..))

Any method defined in the service package or a sub-package:

execution(* com.xyz.service..*.*(..))

see more @ Sharing common pointcut definitions

Proxies

  • Standard JDK dynamic proxies (by interface) (default)
  • CGLIB proxies (by subclassing)
<!-- force to use CGLIB proxies -->

<!-- other beans defined here... -->

AspectJ

A style of declaring aspects as regular Java classes annotated with annotations.
In Spring AOP, it is not possible to have aspects themselves be the target of advice from other aspects. The @Aspect annotation on a class marks it as an aspect, and hence excludes it from auto-proxying.

@Aspect
public class NotVeryUsefulAspect {
@Pointcut("execution(* transfer(..))") // the pointcut expression
private void anyOldTransfer() {}
}

Enabling @AspectJ Support:

<br />

Example

spring-aop.xml

<br /><br /><br /><br /><br />

EntityAspect

public class EntityAspect {
public void prePersist(final GenericEntity entity) {
entity.setCreatedTime(LocalDateTime.now());
entity.setModifiedTime(entity.getCreatedTime());
}
public void preUpdate(final GenericEntity entity) {
entity.setModifiedTime(LocalDateTime.now());
}
}