提交 d96cfc71 编写于 作者: 孙不服 提交者: GitHub

Merge pull request #4220 from apache/revert-4176-orchestration-5.x

Revert "Merger master into orchestration 5.x"

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
github:
description: Distributed database middleware
labels:
- shardingsphere
- database
- distributed-database
- distributed-sql-database
- distributed-transactions
- sql
- shard
- database-cluster
- mysql
- postgresql
- middleware
-Xmx1024m -XX:MaxMetaspaceSize=256m
-Xmx1024m -XX:MaxPermSize=256m
/*
* Copyright 2007-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;
public class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "0.5.5";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
private static final String DEFAULT_DOWNLOAD_URL =
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
......@@ -70,13 +76,13 @@ public class MavenWrapperDownloader {
}
}
}
System.out.println("- Downloading from: " + url);
System.out.println("- Downloading from: : " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
"- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
......@@ -92,16 +98,6 @@ public class MavenWrapperDownloader {
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
......@@ -111,4 +107,4 @@ public class MavenWrapperDownloader {
rbc.close();
}
}
\ No newline at end of file
}
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.1/apache-maven-3.6.1-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
\ No newline at end of file
language: java
jdk:
- openjdk8
install: true
cache:
directories:
- "$HOME/.m2"
before_script:
- echo "MAVEN_OPTS='-Xmx1024m -XX:MaxMetaspaceSize=256m'" > ~/.mavenrc
script:
- travis_wait 30 mvn --batch-mode --no-transfer-progress clean install cobertura:cobertura coveralls:report -DrepoToken="${COVERALLS_REPO_TOKEN}" -Dmaven.javadoc.skip=true
after_success:
- bash <(curl -s https://codecov.io/bash)
after_failure:
- echo "build failed!"
# Contributor Covenant Code of Conduct
The following code of conduct is based on full compliance with [ASF CODE OF CONDUCT](https://www.apache.org/foundation/policies/conduct.html).
## Development Concept
- Write codes with heart. Pursue clean, simplified and extremely elegant codes. Agree with concepts in &lt;Refactoring: Improving the Design of Existing Code&gt; and &lt;Clean Code: A Handbook of Agile Software Craftsmanship&gt;.
......@@ -12,7 +10,7 @@ The following code of conduct is based on full compliance with [ASF CODE OF COND
## Contributor Covenant Submitting of Conduct
- Make sure all the test cases are passed, Make sure `mvn clean install` can be compiled and tested successfully.
- Make sure the test coverage rate is not lower than the master branch.
- Make sure the test coverage rate is not lower than the dev branch.
- Make sure to check codes with Checkstyle. codes that violate check rules should have special reasons. Find checkstyle template from `sharding-sphere/src/resources/sharding_checks.xml`, please use checkstyle `8.8` to run the rules.
## Contributor Covenant Code of Conduct
......@@ -25,20 +23,17 @@ The following code of conduct is based on full compliance with [ASF CODE OF COND
- Return values are named with `result`; Variables in the loop structure are named with `each`; Replace `each` with `entry` in map.
- Exceptions when catch are named with `ex`; Exceptions when catch but do nothing are named with `ignored`.
- Name property files with camel-case and lowercase first letters.
- Split codes that need to add notes with it into small methods, which are explained with method names.
- Have constants on the left and variable on the right in `=` and `equals` conditional expressions; Have variable on the left and constants on the right in `greater than` and `less than` conditional expressions.
- Beside using same names as input parameters and global fields in assign statement, avoid using `this` modifier.
- Have constants on the left and variable on the right in `==` and `equals` conditional expressions; Have variable on the left and constants on the right in `greater than` and `less than` conditional expressions.
- Use `LinkedList` in priority. Use `ArrayList` for use index to get element only.
- Use capacity based `Collection` such as `ArrayList`, `HashMap` must indicate initial capacity to avoid recalculate capacity.
- Design class as `final` class expect abstract class for extend.
- Make nested loop structures a new method.
- Order of members definition and parameters should be consistent during classes and methods.
- Use guard clauses in priority.
- Minimize the access permission for classes and methods.
- Private method should be just next to the method in which it is used; writing private methods should be in the same as the appearance order of private methods.
- No `null` parameters or return values.
- Replace if else return and assign statement with ternary operator in priority.
- Split codes that need to add notes with it into small methods, which are explained with method names.
- Replace constructors, getters, setter methods and log variable with lombok in priority.
- Use `LinkedList` in priority. Use `ArrayList` for use index to get element only.
- Use capacity based `Collection` such as `ArrayList`, `HashMap` must indicate initial capacity to avoid recalculate capacity.
- Use English in all the logs and javadoc.
- Include Javadoc, todo and fixme only in the comments.
- Only `public` classes and methods need javadoc, other methods, classes and override methods do not need javadoc.
......@@ -46,17 +41,7 @@ The following code of conduct is based on full compliance with [ASF CODE OF COND
## Contributor Covenant Unit Test of Conduct
- Test codes and production codes should follow the same kind of code of conduct.
- Unit test should follow AIR (Automatic, Independent, Repeatable) principle.
- Automatic: Unit test should run automatically, not interactively. Check test result manually and `System.out`, `log` are prohibited, use assert to check test results.
- Independent: Call each other and sequence dependency during unit test cases are prohibited. Every test case should run independent.
- Repeatable: Unit test case should not dependency external environment, they can run repeatable.
- Unit test should follow BCDE (Border, Correct, Design, Error) design principle.
- Border: Border value test, test for loop border, special value and value sequence to get expect result.
- Correct: Correct value test, test for correct value to get expect result.
- Design: Design with production codes.
- Error: Error value test, test for error input, exception to get expect result.
- Without particular reasons, test cases should be fully covered.
- Every test case need precised assertion.
- Environment preparation codes should be separate from test codes.
- Only those that relate to junit `Assert`, hamcrest `CoreMatchers` and `Mockito` can use static import.
- For single parameter asserts, `assertTrue`, `assertFalse`, `assertNull` and `assertNotNull` should be used.
......@@ -64,18 +49,3 @@ The following code of conduct is based on full compliance with [ASF CODE OF COND
- For accurate asserts, try not to use `not`, `containsString` to make assertions.
- Actual values of test cases should be named `actualXXX`, expected values `expectedXXX`.
- Class for test case and `@Test` annotation do not need javadoc.
## Contributor Covenant G4 Code of Conduct
- Common Conduct
- Every line cannot over `200` chars, guarantee every line have complete semantics.
- Lexer Conduct
- Every rule should be in single line, no empty line between rules.
- Rule of lexer name should capitalization. If name composite with more than one word, use `underline` to separate. Rule name of `DataType` and `Symbol` should end with `underline`. If rule name is conflicted with ANTLR's keyword, should take an `underline` behind rule name.
- For private rule in lexer should use `fragment`, rule with `fragment` should define behind of public rule which they served.
- Common rule of lexer should put in file `Keyword.g4`, every database may has customized rule file by themselves. For example: `MySQLKeyword.g4`.
- Parser Conduct
- After every rule finish, blank line should no indents.
- No space before rule name definition. One space between `colon` and rule, `semicolon` should take a new line and keep indents (including blank lines) consistent with the previous one.
- If a rule's branch is over than `5`, every branch take a new line.
- Rule name of parser should same with java variable's camel case.
- Define separate files for every SQL type, file name should consist of `database` + `SQL type` + `Statement`. For example: `MySQLDQLStatement.g4`.
......@@ -29,6 +29,6 @@ You can report a bug, submit a new feature enhancement recommendation, or commit
- Find a mentor in [Core developers list](http://incubator.apache.org/projects/shardingsphere.html), he will give you feedback for design and implements.
- Fork to your github repo and begin to work.
- Please follow Sharding's [Development conventions](https://shardingsphere.apache.org/community/en/contribute/code-conduct/), and complete check before pull request submit.
- Submit a pull request to master branch when finished.
- Submit a pull request to dev branch when finished, please do not submit pull request to master.
- Mentor will do code review and discuss some details, include design, implement, performance and code style. Code will be merged until mentor accepted.
- Finally, congratulations that you have become the official contributor for Sharding!
......@@ -29,7 +29,7 @@ Mentors and community members are encouraged to contribute to this page and comm
| **ID** | **Description** | **Status** |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| **LC10** | The code is released under the Apache License, version 2.0. | **YES.** The [LICENSE file](https://github.com/apache/incubator-shardingsphere/blob/dev/LICENSE) is in GitHub repository. |
| **LC20** | Libraries that are mandatory dependencies of the project's code do not create more restrictions than the Apache License does. | **YES.** The [list of dependencies](https://github.com/apache/incubator-shardingsphere/tree/dev/sharding-distribution/sharding-proxy-distribution/src/main/release-docs/licenses) for binary release and [list of dependencies](https://github.com/terrymanu/incubator-shardingsphere/tree/parser/shardingsphere-ui/shardingsphere-ui-distribution/src/main/release-docs/licenses) of UI binary release have been reviewed to contain compatible licenses only. |
| **LC20** | Libraries that are mandatory dependencies of the project's code do not create more restrictions than the Apache License does. | **YES.** The [list of dependencies](https://github.com/apache/incubator-shardingsphere/tree/dev/sharding-distribution/sharding-proxy-distribution/src/main/release-docs/licenses) for binary release and [list of dependencies](https://github.com/apache/incubator-shardingsphere/tree/dev/sharding-distribution/sharding-ui-distribution/src/main/release-docs/licenses) of UI binary release have been reviewed to contain compatible licenses only. |
| **LC30** | The libraries mentioned in LC20 are available as Open Source software. | **YES.** See LC20's dependencies list. |
| **LC40** | Committers are bound by an Individual Contributor Agreement (the "Apache iCLA") that defines which code they are allowed to commit and how they need to identify code that is not their own. | **YES.** All committers have iCLAs on file before they have an apache account. |
| **LC50** | The copyright ownership of everything that the project produces is clearly defined and documented. | **YES.** All files in the source code have appropriate headers and checked by `Apache rat plugin` when build. |
......@@ -82,5 +82,3 @@ Mentors and community members are encouraged to contribute to this page and comm
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| **IN10** | The project is independent from any corporate or organizational influence. | **YES.** The project team gathers people from different companies (JD.com, dangdang.com, CHINA TELECOM Bestpay, DAOCloud). No company or organization has significantly more influence than any other. We can note a growth of the contributions coming from different committers. |
| **IN20** | Contributors act as themselves as opposed to representatives of a corporation or organization. | **YES.** The contributors act on their own initiative without representing a corporation or organization. |
Mentors, PPMCs and committers please discuss and modify on [wiki](https://cwiki.apache.org/confluence/display/SHARDINGSPHERE/Podling+Maturity+Assessment+for+ShardingSphere).
......@@ -9,7 +9,7 @@
[![Total Lines](https://tokei.rs/b1/github/apache/incubator-shardingsphere?category=lines)](https://github.com/apache/incubator-shardingsphere)
[![Build Status](https://builds.apache.org/job/shardingsphere-ci-dev/badge/icon)](https://builds.apache.org/job/shardingsphere-ci-dev/)
[![Coverage Status](https://coveralls.io/repos/github/apache/incubator-shardingsphere/badge.svg?branch=master)](https://coveralls.io/github/apache/incubator-shardingsphere?branch=master)
[![Coverage Status](https://coveralls.io/repos/github/apache/incubator-shardingsphere/badge.svg?branch=dev)](https://coveralls.io/github/apache/incubator-shardingsphere?branch=dev)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/278600ed40ad48e988ab485b439abbcd)](https://www.codacy.com/app/terrymanu/sharding-sphere?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=sharding-sphere/sharding-sphere&amp;utm_campaign=Badge_Grade)
[![snyk](https://snyk.io/test/github/apache/incubator-shardingsphere/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/apache/incubator-shardingsphere?targetFile=pom.xml)
[![OpenTracing-1.0 Badge](https://img.shields.io/badge/OpenTracing--1.0-enabled-blue.svg)](http://opentracing.io)
......@@ -49,7 +49,7 @@ It can be considered as an enhanced JDBC driver, which is fully compatible with
### Sharding-Proxy
[![Download](https://img.shields.io/badge/release-download-orange.svg)](https://www.apache.org/dyn/closer.cgi?path=incubator/shardingsphere/4.0.0/apache-shardingsphere-incubating-4.0.0-sharding-proxy-bin.tar.gz)
[![Download](https://img.shields.io/badge/release-download-orange.svg)](https://www.apache.org/dyn/closer.cgi?path=incubator/shardingsphere/4.0.0-RC2/apache-shardingsphere-incubating-4.0.0-RC2-sharding-proxy-bin.tar.gz)
[![Docker Pulls](https://img.shields.io/docker/pulls/shardingsphere/sharding-proxy.svg)](https://store.docker.com/community/images/shardingsphere/sharding-proxy)
Sharding-Proxy defines itself as a transparent database proxy, providing a database server that encapsulates database binary protocol to support heterogeneous languages.
......@@ -121,38 +121,15 @@ Architects can adjust the system architecture to the most applicable one to curr
## How to Build
### Build ShardingSphere
```bash
./mvnw clean install -Prelease
```
```
Artifact:
```
sharding-distribution/sharding-jdbc-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-jdbc-bin.tar.gz: Binary package of Sharding-JDBC
sharding-distribution/sharding-proxy-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-proxy-bin.tar.gz: Binary package of Sharding-Proxy
sharding-distribution/sharding-ui-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-ui-bin.tar.gz: Binary package of Sharding-UI
sharding-distribution/shardingsphere-src-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-src.zip: Source code package of ShardingSphere
```
### Build ShardingSphere-UI
```bash
cd shardingsphere-ui
./mvnw clean install -Prelease
```
Artifact:
```
shardingsphere-ui/shardingsphere-ui-distribution/shardingsphere-ui-bin-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-shardingsphere-ui-bin.tar.gz: Binary package of ShardingSphere-UI
```
## Landscapes
<p align="center">
<br/><br/>
<img src="https://landscape.cncf.io/images/left-logo.svg" width="150"/>&nbsp;&nbsp;<img src="https://landscape.cncf.io/images/right-logo.svg" width="200"/>
<br/><br/>
ShardingSphere enriches the <a href="https://landscape.cncf.io/landscape=observability-and-analysis&license=apache-license-2-0">CNCF CLOUD NATIVE Landscape.</a>
</p>
......@@ -9,7 +9,7 @@
[![Total Lines](https://tokei.rs/b1/github/apache/incubator-shardingsphere?category=lines)](https://github.com/apache/incubator-shardingsphere)
[![Build Status](https://builds.apache.org/job/shardingsphere-ci-dev/badge/icon)](https://builds.apache.org/job/shardingsphere-ci-dev/)
[![Coverage Status](https://coveralls.io/repos/github/apache/incubator-shardingsphere/badge.svg?branch=master)](https://coveralls.io/github/apache/incubator-shardingsphere?branch=master)
[![Coverage Status](https://coveralls.io/repos/github/apache/incubator-shardingsphere/badge.svg?branch=dev)](https://coveralls.io/github/apache/incubator-shardingsphere?branch=dev)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/278600ed40ad48e988ab485b439abbcd)](https://www.codacy.com/app/terrymanu/sharding-sphere?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=sharding-sphere/sharding-sphere&amp;utm_campaign=Badge_Grade)
[![snyk](https://snyk.io/test/github/apache/incubator-shardingsphere/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/apache/incubator-shardingsphere?targetFile=pom.xml)
[![OpenTracing-1.0 Badge](https://img.shields.io/badge/OpenTracing--1.0-enabled-blue.svg)](http://opentracing.io)
......@@ -50,7 +50,7 @@ __Apache官方发布从4.0.0版本开始。__
### Sharding-Proxy
[![Download](https://img.shields.io/badge/release-download-orange.svg)](https://www.apache.org/dyn/closer.cgi?path=incubator/shardingsphere/4.0.0/apache-shardingsphere-incubating-4.0.0-sharding-proxy-bin.tar.gz)
[![Download](https://img.shields.io/badge/release-download-orange.svg)](https://www.apache.org/dyn/closer.cgi?path=incubator/shardingsphere/4.0.0-RC2/apache-shardingsphere-incubating-4.0.0-RC2-sharding-proxy-bin.tar.gz)
[![Docker Pulls](https://img.shields.io/docker/pulls/shardingsphere/sharding-proxy.svg)](https://store.docker.com/community/images/shardingsphere/sharding-proxy)
定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。
......@@ -118,8 +118,6 @@ ShardingSphere是多接入端共同组成的生态圈。
## 如何构建
### 构建ShardingSphere
```bash
./mvnw clean install -Prelease
```
......@@ -129,27 +127,6 @@ ShardingSphere是多接入端共同组成的生态圈。
```
sharding-distribution/sharding-jdbc-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-jdbc-bin.tar.gz: Sharding-JDBC的二进制包
sharding-distribution/sharding-proxy-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-proxy-bin.tar.gz: Sharding-Proxy的二进制包
sharding-distribution/sharding-ui-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-sharding-ui-bin.tar.gz: Sharding-UI的二进制包
sharding-distribution/shardingsphere-src-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-src.zip: ShardingSphere的源码包
```
### 构建ShardingSphere UI
```bash
cd shardingsphere-ui
./mvnw clean install -Prelease
```
构建产物:
```
shardingsphere-ui/shardingsphere-ui-distribution/shardingsphere-ui-bin-distribution/target/apache-shardingsphere-incubating-${latest.release.version}-shardingsphere-ui-bin.tar.gz: ShardingSphere-UI的二进制包
```
## 全景图
<p align="center">
<br/><br/>
<img src="https://landscape.cncf.io/images/left-logo.svg" width="150"/>&nbsp;&nbsp;<img src="https://landscape.cncf.io/images/right-logo.svg" width="200"/>
<br/><br/>
ShardingSphere进入了<a href="https://landscape.cncf.io/landscape=observability-and-analysis&license=apache-license-2-0">CNCF云原生全景图。</a>
</p>
## 4.0.0
### API Changes
1. Change package and maven groupId form `io.shardingsphere` to `org.apache.shardingsphere`.
1. Adjust Sharding-JDBC configuration API.
1. Adjust persist structure for registry center.
### New Features
1. SQL92 Syntax available.
1. Sharding-Proxy for PostgreSQL protocol available.
1. SQL 100% compatible if route to single data node.
1. Less-than(<), greater-than(>) and Less-than-equal(<=), greater-than-equal(>=) for sharding key operator available.
1. DISTINCT SQL syntax available.
1. Broadcast table available.
1. LEAF key generator available.
1. XA Transaction available, Atomikos, Narayana and Bitronix integrated.
1. BASE Transaction available, Seata integrated.
1. Data encrypt available.
1. Skywalking plugin available.
1. ShardingSphere-UI available, an orchestration management platform.
### Enhancement
1. MariaDB supported.
1. Improve the compatibility of SQL parsing.
1. `SELECT FOR UPDATE` route to master data source only.
1. Hint in Sharding-Proxy available.
1. Make configuration of orchestration consistent between Sharding-JDBC and Sharding-Proxy.
1. Renew modified data sources only, not renew all the data sources.
1. Vibrate configurable for Snowflake key generator.
### Bug Fixes
1. Improve the compatibility of JDBC Driver URL.
1. Delete statement with alias available.
1. Check and disable updating sharding column.
1. Fix wrong type of TINYINT and SMALLINT as INTEGER.
### Change Logs
1. [MILESTONE #3](https://github.com/sharding-sphere/sharding-sphere/milestone/3)
1. [MILESTONE #4](https://github.com/sharding-sphere/sharding-sphere/milestone/4)
1. [MILESTONE #5](https://github.com/sharding-sphere/sharding-sphere/milestone/5)
1. [MILESTONE #6](https://github.com/sharding-sphere/sharding-sphere/milestone/6)
1. [MILESTONE #7](https://github.com/apache/incubator-shardingsphere/milestone/7)
1. [MILESTONE #8](https://github.com/apache/incubator-shardingsphere/milestone/8)
1. [MILESTONE #9](https://github.com/apache/incubator-shardingsphere/milestone/9)
## 4.0.0.RC3
### New Features
1. ShardingSphere-UI, an orchestration management platform for ShardingSphere comes online.
1. Sharding-UI, an orchestration management platform for ShardingSphere comes online.
1. Not only SQLs from MySQL, PostgreSQL, SQLServer, Oracle, but any SQL92 Syntax can be parsed correctly and used in ShardingSphere.
### Enhancement
......@@ -60,14 +10,14 @@
1. Support using less-than character(<) and greater-than character(>) for sharding data.
1. When master and slave dataSources exist, support executing `SELECT FOR UPDATE` on master dataSource.
1. Support hint in Sharding-Proxy.
1. Finish parsing DAL syntax for MySQL.
1. Finish to parse DAL syntax for MySQL.
1. Make configuration of orchestration compatible between Sharding-JDBC and Sharding-Proxy.
### Bug Fixes
1. Through Bug fix, the feature of encryption becomes much stable and applicable.
1. Support delete statement with alias.
1. Check and disable updating sharding column.
1. Check and disable update sharding column.
1. Fix wrong type of TINYINT and SMALLINT as INTEGER.
### Refactor
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>encrypt-core</artifactId>
<version>5.0.0-RC1-SNAPSHOT</version>
</parent>
<artifactId>encrypt-core-api</artifactId>
<name>${project.artifactId}</name>
<dependencies>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.api;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* Encrypt column rule configuration.
*
* @author panjuan
*/
@RequiredArgsConstructor
@Getter
public final class EncryptColumnRuleConfiguration {
private final String plainColumn;
private final String cipherColumn;
private final String assistedQueryColumn;
private final String encryptor;
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.api;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.underlying.common.config.RuleConfiguration;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Encrypt rule configuration.
*
* @author panjuan
*/
@RequiredArgsConstructor
@Getter
public final class EncryptRuleConfiguration implements RuleConfiguration {
private final Map<String, EncryptorRuleConfiguration> encryptors;
private final Map<String, EncryptTableRuleConfiguration> tables;
public EncryptRuleConfiguration() {
this(new LinkedHashMap<String, EncryptorRuleConfiguration>(), new LinkedHashMap<String, EncryptTableRuleConfiguration>());
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.api;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Encrypt table rule configuration.
*
* @author panjuan
*/
@NoArgsConstructor
@Getter
public final class EncryptTableRuleConfiguration {
private final Map<String, EncryptColumnRuleConfiguration> columns = new LinkedHashMap<>();
public EncryptTableRuleConfiguration(final Map<String, EncryptColumnRuleConfiguration> columns) {
this.columns.putAll(columns);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.api;
import lombok.Getter;
import org.apache.shardingsphere.underlying.common.config.TypeBasedSPIConfiguration;
import java.util.Properties;
/**
* Encryptor configuration.
*
* @author panjuan
*/
@Getter
public final class EncryptorRuleConfiguration extends TypeBasedSPIConfiguration {
public EncryptorRuleConfiguration(final String type, final Properties properties) {
super(type, properties);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.api;
import org.junit.Test;
import java.util.Properties;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public final class EncryptorRuleConfigurationTest {
@Test(expected = IllegalArgumentException.class)
public void assertConstructorWithoutType() {
new EncryptorRuleConfiguration(null, new Properties());
}
@Test
public void assertConstructorWithoutAssistedQueryColumnsAndProperties() {
EncryptorRuleConfiguration actual = new EncryptorRuleConfiguration("TEST", new Properties());
assertThat(actual.getType(), is("TEST"));
assertThat(actual.getProperties(), is(new Properties()));
}
@Test
public void assertConstructorWithMinArguments() {
Properties props = new Properties();
props.setProperty("key", "value");
EncryptorRuleConfiguration actual = new EncryptorRuleConfiguration("TEST", props);
assertThat(actual.getType(), is("TEST"));
assertThat(actual.getProperties(), is(props));
}
@Test
public void assertConstructorWithMaxArguments() {
Properties props = new Properties();
props.setProperty("key", "value");
EncryptorRuleConfiguration actual = new EncryptorRuleConfiguration("TEST", props);
assertThat(actual.getType(), is("TEST"));
assertThat(actual.getProperties(), is(props));
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>encrypt-core</artifactId>
<version>5.0.0-RC1-SNAPSHOT</version>
</parent>
<artifactId>encrypt-core-common</artifactId>
<name>${project.artifactId}</name>
<dependencies>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>encrypt-core-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.metadata;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import org.apache.shardingsphere.underlying.common.metadata.column.ColumnMetaData;
/**
* Column meta data for encrypt.
*
* @author zhangliang
*/
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class EncryptColumnMetaData extends ColumnMetaData {
private final String cipherColumnName;
private final String plainColumnName;
private final String assistedQueryColumnName;
public EncryptColumnMetaData(final String name, final String dataType, final boolean primaryKey, final String cipherColumnName,
final String plainColumnName, final String assistedQueryColumnName) {
super(name, dataType, primaryKey);
this.cipherColumnName = cipherColumnName;
this.plainColumnName = plainColumnName;
this.assistedQueryColumnName = assistedQueryColumnName;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.metadata.decorator;
import org.apache.shardingsphere.encrypt.metadata.EncryptColumnMetaData;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.underlying.common.metadata.column.ColumnMetaData;
import org.apache.shardingsphere.underlying.common.metadata.table.TableMetaData;
import org.apache.shardingsphere.underlying.common.metadata.table.TableMetas;
import org.apache.shardingsphere.underlying.common.metadata.table.init.decorator.TableMetaDataDecorator;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
/**
* Table meta data decorator for encrypt.
*
* @author zhangliang
*/
public final class EncryptTableMetaDataDecorator implements TableMetaDataDecorator<EncryptRule> {
@Override
public TableMetas decorate(final TableMetas tableMetas, final EncryptRule encryptRule) {
Map<String, TableMetaData> result = new HashMap<>(tableMetas.getAllTableNames().size(), 1);
for (String each : tableMetas.getAllTableNames()) {
result.put(each, decorate(tableMetas.get(each), each, encryptRule));
}
return new TableMetas(result);
}
@Override
public TableMetaData decorate(final TableMetaData tableMetaData, final String tableName, final EncryptRule encryptRule) {
return new TableMetaData(getEncryptColumnMetaDataList(tableName, tableMetaData.getColumns().values(), encryptRule), tableMetaData.getIndexes());
}
private Collection<ColumnMetaData> getEncryptColumnMetaDataList(final String tableName, final Collection<ColumnMetaData> originalColumnMetaDataList, final EncryptRule encryptRule) {
Collection<ColumnMetaData> result = new LinkedList<>();
Collection<String> derivedColumns = encryptRule.getAssistedQueryAndPlainColumns(tableName);
for (ColumnMetaData each : originalColumnMetaDataList) {
if (!derivedColumns.contains(each.getName())) {
result.add(getEncryptColumnMetaData(tableName, each, encryptRule));
}
}
return result;
}
private ColumnMetaData getEncryptColumnMetaData(final String tableName, final ColumnMetaData originalColumnMetaData, final EncryptRule encryptRule) {
if (!encryptRule.isCipherColumn(tableName, originalColumnMetaData.getName())) {
return originalColumnMetaData;
}
String logicColumnName = encryptRule.getLogicColumnOfCipher(tableName, originalColumnMetaData.getName());
String plainColumnName = encryptRule.findPlainColumn(tableName, logicColumnName).orNull();
String assistedQueryColumnName = encryptRule.findAssistedQueryColumn(tableName, logicColumnName).orNull();
return new EncryptColumnMetaData(
logicColumnName, originalColumnMetaData.getDataType(), originalColumnMetaData.isPrimaryKey(), originalColumnMetaData.getName(), plainColumnName, assistedQueryColumnName);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.metadata.loader;
import org.apache.shardingsphere.encrypt.metadata.decorator.EncryptTableMetaDataDecorator;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.underlying.common.metadata.datasource.DataSourceMetas;
import org.apache.shardingsphere.underlying.common.metadata.table.TableMetaData;
import org.apache.shardingsphere.underlying.common.metadata.table.TableMetas;
import org.apache.shardingsphere.underlying.common.metadata.table.init.loader.ConnectionManager;
import org.apache.shardingsphere.underlying.common.metadata.table.init.loader.TableMetaDataLoader;
import org.apache.shardingsphere.underlying.common.metadata.table.init.loader.impl.DefaultTableMetaDataLoader;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* Table meta data loader for encrypt.
*
* @author zhangliang
* @author panjuan
*/
public final class EncryptTableMetaDataLoader implements TableMetaDataLoader<EncryptRule> {
private final DefaultTableMetaDataLoader defaultTableMetaDataLoader;
private final EncryptTableMetaDataDecorator encryptTableMetaDataDecorator;
public EncryptTableMetaDataLoader(final DataSourceMetas dataSourceMetas, final ConnectionManager connectionManager) {
defaultTableMetaDataLoader = new DefaultTableMetaDataLoader(dataSourceMetas, connectionManager);
encryptTableMetaDataDecorator = new EncryptTableMetaDataDecorator();
}
@Override
public TableMetaData load(final String tableName, final EncryptRule encryptRule) throws SQLException {
return encryptTableMetaDataDecorator.decorate(defaultTableMetaDataLoader.load(tableName, encryptRule), tableName, encryptRule);
}
@Override
public TableMetas loadAll(final EncryptRule encryptRule) throws SQLException {
TableMetas tableMetas = defaultTableMetaDataLoader.loadAll(encryptRule);
Collection<String> allTableNames = tableMetas.getAllTableNames();
Map<String, TableMetaData> result = new HashMap<>(allTableNames.size(), 1);
for (String each : allTableNames) {
result.put(each, encryptTableMetaDataDecorator.decorate(tableMetas.get(each), each, encryptRule));
}
return new TableMetas(result);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rule;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import lombok.Getter;
import org.apache.shardingsphere.encrypt.api.EncryptColumnRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptTableRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptorRuleConfiguration;
import org.apache.shardingsphere.encrypt.strategy.spi.loader.EncryptorServiceLoader;
import org.apache.shardingsphere.encrypt.strategy.EncryptTable;
import org.apache.shardingsphere.encrypt.strategy.spi.Encryptor;
import org.apache.shardingsphere.encrypt.strategy.spi.QueryAssistedEncryptor;
import org.apache.shardingsphere.underlying.common.rule.BaseRule;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Encrypt rule.
*
* @author panjuan
*/
public final class EncryptRule implements BaseRule {
private final Map<String, Encryptor> encryptors = new LinkedHashMap<>();
private final Map<String, EncryptTable> tables = new LinkedHashMap<>();
@Getter
private EncryptRuleConfiguration ruleConfiguration;
public EncryptRule() {
ruleConfiguration = new EncryptRuleConfiguration();
}
public EncryptRule(final EncryptRuleConfiguration encryptRuleConfig) {
this.ruleConfiguration = encryptRuleConfig;
Preconditions.checkArgument(isValidRuleConfiguration(), "Invalid encrypt column configurations in EncryptTableRuleConfigurations.");
initEncryptors(encryptRuleConfig.getEncryptors());
initTables(encryptRuleConfig.getTables());
}
private boolean isValidRuleConfiguration() {
return (ruleConfiguration.getEncryptors().isEmpty() && ruleConfiguration.getTables().isEmpty()) || isValidTableConfiguration();
}
private boolean isValidTableConfiguration() {
for (EncryptTableRuleConfiguration table : ruleConfiguration.getTables().values()) {
for (EncryptColumnRuleConfiguration column : table.getColumns().values()) {
if (!isValidColumnConfiguration(column)) {
return false;
}
}
}
return true;
}
private boolean isValidColumnConfiguration(final EncryptColumnRuleConfiguration column) {
return !Strings.isNullOrEmpty(column.getEncryptor()) && !Strings.isNullOrEmpty(column.getCipherColumn()) && ruleConfiguration.getEncryptors().containsKey(column.getEncryptor());
}
private void initEncryptors(final Map<String, EncryptorRuleConfiguration> encryptors) {
EncryptorServiceLoader serviceLoader = new EncryptorServiceLoader();
for (Entry<String, EncryptorRuleConfiguration> entry : encryptors.entrySet()) {
this.encryptors.put(entry.getKey(), createEncryptor(serviceLoader, entry.getValue()));
}
}
private Encryptor createEncryptor(final EncryptorServiceLoader serviceLoader, final EncryptorRuleConfiguration encryptorRuleConfig) {
Encryptor result = serviceLoader.newService(encryptorRuleConfig.getType(), encryptorRuleConfig.getProperties());
result.init();
return result;
}
private void initTables(final Map<String, EncryptTableRuleConfiguration> tables) {
for (Entry<String, EncryptTableRuleConfiguration> entry : tables.entrySet()) {
this.tables.put(entry.getKey(), new EncryptTable(entry.getValue()));
}
}
/**
* Find encrypt table.
*
* @param logicTable logic table
* @return encrypt table
*/
public Optional<EncryptTable> findEncryptTable(final String logicTable) {
return Optional.fromNullable(tables.get(logicTable));
}
/**
* Get logic column of cipher column.
*
* @param logicTable logic table
* @param cipherColumn cipher column
* @return logic column
*/
public String getLogicColumnOfCipher(final String logicTable, final String cipherColumn) {
return tables.get(logicTable).getLogicColumnOfCipher(cipherColumn);
}
/**
* Find plain column.
*
* @param logicTable logic table name
* @param logicColumn logic column name
* @return plain column
*/
public Optional<String> findPlainColumn(final String logicTable, final String logicColumn) {
Optional<String> originColumnName = findOriginColumnName(logicTable, logicColumn);
return originColumnName.isPresent() && tables.containsKey(logicTable) ? tables.get(logicTable).findPlainColumn(originColumnName.get()) : Optional.<String>absent();
}
private Optional<String> findOriginColumnName(final String logicTable, final String logicColumn) {
for (String each : tables.get(logicTable).getLogicColumns()) {
if (logicColumn.equalsIgnoreCase(each)) {
return Optional.of(each);
}
}
return Optional.absent();
}
/**
* Get cipher column.
*
* @param logicTable logic table name
* @param logicColumn logic column name
* @return cipher column
*/
public String getCipherColumn(final String logicTable, final String logicColumn) {
return tables.get(logicTable).getCipherColumn(logicColumn);
}
/**
* Is cipher column or not.
*
* @param tableName table name
* @param columnName column name
* @return cipher column or not
*/
public boolean isCipherColumn(final String tableName, final String columnName) {
return tables.containsKey(tableName) && tables.get(tableName).getCipherColumns().contains(columnName);
}
/**
* Find assisted query column.
*
* @param logicTable logic table name
* @param logicColumn column name
* @return assisted query column
*/
public Optional<String> findAssistedQueryColumn(final String logicTable, final String logicColumn) {
return tables.containsKey(logicTable) ? tables.get(logicTable).findAssistedQueryColumn(logicColumn) : Optional.<String>absent();
}
/**
* Get assisted query columns.
*
* @param logicTable logic table
* @return assisted query columns
*/
public Collection<String> getAssistedQueryColumns(final String logicTable) {
return tables.containsKey(logicTable) ? tables.get(logicTable).getAssistedQueryColumns() : Collections.<String>emptyList();
}
/**
* Get assisted query and plain columns.
*
* @param logicTable logic table name
* @return assisted query and plain columns
*/
public Collection<String> getAssistedQueryAndPlainColumns(final String logicTable) {
Collection<String> result = new LinkedList<>();
result.addAll(getAssistedQueryColumns(logicTable));
result.addAll(getPlainColumns(logicTable));
return result;
}
private Collection<String> getPlainColumns(final String logicTable) {
return tables.containsKey(logicTable) ? tables.get(logicTable).getPlainColumns() : Collections.<String>emptyList();
}
/**
* Get logic and cipher columns.
*
* @param logicTable logic table
* @return logic and cipher columns
*/
public Map<String, String> getLogicAndCipherColumns(final String logicTable) {
return tables.containsKey(logicTable) ? tables.get(logicTable).getLogicAndCipherColumns() : Collections.<String, String>emptyMap();
}
/**
* Get logic and plain columns.
*
* @param logicTable logic table
* @return logic and plain columns
*/
public Map<String, String> getLogicAndPlainColumns(final String logicTable) {
return tables.containsKey(logicTable) ? tables.get(logicTable).getLogicAndPlainColumns() : Collections.<String, String>emptyMap();
}
/**
* Get encrypt assisted query values.
*
* @param logicTable logic table
* @param logicColumn logic column
* @param originalValues original values
* @return assisted query values
*/
public List<Object> getEncryptAssistedQueryValues(final String logicTable, final String logicColumn, final List<Object> originalValues) {
final Optional<Encryptor> encryptor = findEncryptor(logicTable, logicColumn);
Preconditions.checkArgument(encryptor.isPresent() && encryptor.get() instanceof QueryAssistedEncryptor,
String.format("Can not find QueryAssistedEncryptor by %s.%s.", logicTable, logicColumn));
return Lists.transform(originalValues, new Function<Object, Object>() {
@Override
public Object apply(final Object input) {
return null == input ? null : ((QueryAssistedEncryptor) encryptor.get()).queryAssistedEncrypt(input.toString());
}
});
}
/**
* get encrypt values.
*
* @param logicTable logic table
* @param logicColumn logic column
* @param originalValues original values
* @return encrypt values
*/
public List<Object> getEncryptValues(final String logicTable, final String logicColumn, final List<Object> originalValues) {
final Optional<Encryptor> encryptor = findEncryptor(logicTable, logicColumn);
Preconditions.checkArgument(encryptor.isPresent(), String.format("Can not find QueryAssistedEncryptor by %s.%s.", logicTable, logicColumn));
return Lists.transform(originalValues, new Function<Object, Object>() {
@Override
public Object apply(final Object input) {
return null == input ? null : String.valueOf(encryptor.get().encrypt(input.toString()));
}
});
}
/**
* Find sharding encryptor.
*
* @param logicTable logic table name
* @param logicColumn logic column name
* @return sharding encryptor
*/
public Optional<Encryptor> findEncryptor(final String logicTable, final String logicColumn) {
if (!tables.containsKey(logicTable)) {
return Optional.absent();
}
Optional<String> encryptor = tables.get(logicTable).findEncryptor(logicColumn);
return encryptor.isPresent() ? Optional.of(encryptors.get(encryptor.get())) : Optional.<Encryptor>absent();
}
/**
* Get encrypt table names.
*
* @return encrypt table names
*/
public Collection<String> getEncryptTableNames() {
return tables.keySet();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rule.aware;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
/**
* Encrypt rule aware.
*
* @author zhangliang
*/
public interface EncryptRuleAware {
/**
* Set encrypt rule.
*
* @param encryptRule encrypt rule
*/
void setEncryptRule(EncryptRule encryptRule);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* Encrypt column.
*
* @author panjuan
*/
@RequiredArgsConstructor
@Getter
public final class EncryptColumn {
private final String cipherColumn;
private final String assistedQueryColumn;
private final String plainColumn;
private final String encryptor;
/**
* Get assisted query column.
*
* @return assisted query column
*/
public Optional<String> getAssistedQueryColumn() {
return Strings.isNullOrEmpty(assistedQueryColumn) ? Optional.<String>absent() : Optional.of(assistedQueryColumn);
}
/**
* Get plain column.
*
* @return plain column
*/
public Optional<String> getPlainColumn() {
return Strings.isNullOrEmpty(plainColumn) ? Optional.<String>absent() : Optional.of(plainColumn);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.Maps;
import org.apache.shardingsphere.encrypt.api.EncryptColumnRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptTableRuleConfiguration;
import org.apache.shardingsphere.underlying.common.exception.ShardingSphereException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
/**
* Encryptor table.
*
* @author panjuan
*/
public final class EncryptTable {
private final Map<String, EncryptColumn> columns;
public EncryptTable(final EncryptTableRuleConfiguration config) {
columns = new LinkedHashMap<>(new LinkedHashMap<>(Maps.transformValues(config.getColumns(), new Function<EncryptColumnRuleConfiguration, EncryptColumn>() {
@Override
public EncryptColumn apply(final EncryptColumnRuleConfiguration input) {
return new EncryptColumn(input.getCipherColumn(), input.getAssistedQueryColumn(), input.getPlainColumn(), input.getEncryptor());
}
})));
}
/**
* Get logic column of cipher column.
*
* @param cipherColumn cipher column
* @return logic column
*/
public String getLogicColumnOfCipher(final String cipherColumn) {
for (Entry<String, EncryptColumn> entry : columns.entrySet()) {
if (entry.getValue().getCipherColumn().equals(cipherColumn)) {
return entry.getKey();
}
}
throw new ShardingSphereException("Can not find logic column by %s.", cipherColumn);
}
/**
* Get logic columns.
*
* @return logic column
*/
public Collection<String> getLogicColumns() {
return columns.keySet();
}
/**
* Find plain column.
*
* @param logicColumn logic column name
* @return plain column
*/
public Optional<String> findPlainColumn(final String logicColumn) {
return columns.containsKey(logicColumn) ? columns.get(logicColumn).getPlainColumn() : Optional.<String>absent();
}
/**
* Get plain columns.
*
* @return plain columns
*/
public Collection<String> getPlainColumns() {
Collection<String> result = new LinkedList<>();
for (EncryptColumn each : columns.values()) {
if (each.getPlainColumn().isPresent()) {
result.add(each.getPlainColumn().get());
}
}
return result;
}
/**
* Get cipher column.
*
* @param logicColumn logic column name
* @return cipher column
*/
public String getCipherColumn(final String logicColumn) {
return columns.get(logicColumn).getCipherColumn();
}
/**
* Get cipher columns.
*
* @return cipher columns
*/
public Collection<String> getCipherColumns() {
Collection<String> result = new LinkedList<>();
for (EncryptColumn each : columns.values()) {
result.add(each.getCipherColumn());
}
return result;
}
/**
* Find assisted query column.
*
* @param logicColumn column name
* @return assisted query column
*/
public Optional<String> findAssistedQueryColumn(final String logicColumn) {
return columns.containsKey(logicColumn) ? columns.get(logicColumn).getAssistedQueryColumn() : Optional.<String>absent();
}
/**
* Get assisted query columns.
*
* @return assisted query columns
*/
public Collection<String> getAssistedQueryColumns() {
Collection<String> result = new LinkedList<>();
for (EncryptColumn each : columns.values()) {
if (each.getAssistedQueryColumn().isPresent()) {
result.add(each.getAssistedQueryColumn().get());
}
}
return result;
}
/**
* Find encryptor.
*
* @param logicColumn column name
* @return encryptor
*/
public Optional<String> findEncryptor(final String logicColumn) {
Optional<String> originLogicColumnName = findOriginLogicColumnName(logicColumn);
return originLogicColumnName.isPresent() && columns.containsKey(originLogicColumnName.get()) ? Optional.of(columns.get(originLogicColumnName.get()).getEncryptor()) : Optional.<String>absent();
}
private Optional<String> findOriginLogicColumnName(final String logicColumn) {
for (String each : columns.keySet()) {
if (logicColumn.equalsIgnoreCase(each)) {
return Optional.of(each);
}
}
return Optional.absent();
}
/**
* Get logic and cipher columns.
*
* @return logic and cipher columns
*/
public Map<String, String> getLogicAndCipherColumns() {
return Maps.transformValues(columns, new Function<EncryptColumn, String>() {
@Override
public String apply(final EncryptColumn input) {
return input.getCipherColumn();
}
});
}
/**
* Get logic and plain columns.
*
* @return logic and plain columns
*/
public Map<String, String> getLogicAndPlainColumns() {
return Maps.transformValues(columns, new Function<EncryptColumn, String>() {
@Override
public String apply(final EncryptColumn input) {
if (input.getPlainColumn().isPresent()) {
return input.getPlainColumn().get();
}
throw new ShardingSphereException("Plain column is null.");
}
});
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.impl;
import com.google.common.base.Preconditions;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.shardingsphere.encrypt.strategy.spi.Encryptor;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Properties;
/**
* AES encryptor.
*
* @author panjuan
*/
@Getter
@Setter
public final class AESEncryptor implements Encryptor {
private static final String AES_KEY = "aes.key.value";
private Properties properties = new Properties();
@Override
public String getType() {
return "AES";
}
@Override
public void init() {
}
@Override
@SneakyThrows
public String encrypt(final Object plaintext) {
if (null == plaintext) {
return null;
}
byte[] result = getCipher(Cipher.ENCRYPT_MODE).doFinal(StringUtils.getBytesUtf8(String.valueOf(plaintext)));
return Base64.encodeBase64String(result);
}
@Override
@SneakyThrows
public Object decrypt(final String ciphertext) {
if (null == ciphertext) {
return null;
}
byte[] result = getCipher(Cipher.DECRYPT_MODE).doFinal(Base64.decodeBase64(ciphertext));
return new String(result, StandardCharsets.UTF_8);
}
private Cipher getCipher(final int decryptMode) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
Preconditions.checkArgument(properties.containsKey(AES_KEY), "No available secret key for `%s`.", AESEncryptor.class.getName());
Cipher result = Cipher.getInstance(getType());
result.init(decryptMode, new SecretKeySpec(createSecretKey(), getType()));
return result;
}
private byte[] createSecretKey() {
Preconditions.checkArgument(null != properties.get(AES_KEY), String.format("%s can not be null.", AES_KEY));
return Arrays.copyOf(DigestUtils.sha1(properties.get(AES_KEY).toString()), 16);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.impl;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.shardingsphere.encrypt.strategy.spi.Encryptor;
import java.util.Properties;
/**
* MD5 encryptor.
*
* @author panjuan
*/
@Getter
@Setter
public final class MD5Encryptor implements Encryptor {
private Properties properties = new Properties();
@Override
public String getType() {
return "MD5";
}
@Override
public void init() {
}
@Override
public String encrypt(final Object plaintext) {
if (null == plaintext) {
return null;
}
return DigestUtils.md5Hex(String.valueOf(plaintext));
}
@Override
public Object decrypt(final String ciphertext) {
return ciphertext;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.spi;
import org.apache.shardingsphere.spi.TypeBasedSPI;
/**
* Encryptor.
*
* @author panjuan
*/
public interface Encryptor extends TypeBasedSPI {
/**
* Initialize.
*/
void init();
/**
* Encode.
*
* @param plaintext plaintext
* @return ciphertext
*/
String encrypt(Object plaintext);
/**
* Decode.
*
* @param ciphertext ciphertext
* @return plaintext
*/
Object decrypt(String ciphertext);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.spi;
/**
* Query assisted encryptor.
*
* @author panjuan
*/
public interface QueryAssistedEncryptor extends Encryptor {
/**
* Query assisted encrypt.
*
* @param plaintext plaintext
* @return ciphertext
*/
String queryAssistedEncrypt(String plaintext);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.spi.loader;
import org.apache.shardingsphere.spi.NewInstanceServiceLoader;
import org.apache.shardingsphere.spi.TypeBasedSPIServiceLoader;
import org.apache.shardingsphere.encrypt.strategy.spi.Encryptor;
/**
* Encryptor service loader.
*
* @author panjuan
*/
public final class EncryptorServiceLoader extends TypeBasedSPIServiceLoader<Encryptor> {
static {
NewInstanceServiceLoader.register(Encryptor.class);
}
public EncryptorServiceLoader() {
super(Encryptor.class);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.yaml.config;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.underlying.common.yaml.config.YamlConfiguration;
/**
* Encrypt column rule configuration.
*
* @author panjuan
*/
@Getter
@Setter
public final class YamlEncryptColumnRuleConfiguration implements YamlConfiguration {
private String plainColumn;
private String cipherColumn;
private String assistedQueryColumn;
private String encryptor;
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.yaml.config;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.underlying.common.yaml.config.YamlConfiguration;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Encrypt rule configuration.
*
* @author panjuan
*/
@Getter
@Setter
public class YamlEncryptRuleConfiguration implements YamlConfiguration {
private Map<String, YamlEncryptorRuleConfiguration> encryptors = new LinkedHashMap<>();
private Map<String, YamlEncryptTableRuleConfiguration> tables = new LinkedHashMap<>();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.yaml.config;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.underlying.common.yaml.config.YamlConfiguration;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Encrypt table rule configuration.
*
* @author panjuan
*/
@Getter
@Setter
public final class YamlEncryptTableRuleConfiguration implements YamlConfiguration {
private Map<String, YamlEncryptColumnRuleConfiguration> columns = new LinkedHashMap<>();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.yaml.config;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.underlying.common.yaml.config.YamlConfiguration;
import java.util.Properties;
/**
* Encryptor configuration.
*
* @author panjuan
*/
@Getter
@Setter
public final class YamlEncryptorRuleConfiguration implements YamlConfiguration {
private String type;
private Properties props = new Properties();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.yaml.config;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.underlying.common.yaml.config.YamlConfiguration;
import javax.sql.DataSource;
import java.util.Properties;
/**
* Root encrypt rule configuration for YAML.
*
* @author panjuan
*/
@Getter
@Setter
public class YamlRootEncryptRuleConfiguration implements YamlConfiguration {
private DataSource dataSource;
private YamlEncryptRuleConfiguration encryptRule;
private Properties props = new Properties();
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.yaml.swapper;
import org.apache.shardingsphere.encrypt.api.EncryptColumnRuleConfiguration;
import org.apache.shardingsphere.encrypt.yaml.config.YamlEncryptColumnRuleConfiguration;
import org.apache.shardingsphere.underlying.common.yaml.swapper.YamlSwapper;
/**
* Encrypt column configuration YAML swapper.
*
* @author panjuan
*/
public final class EncryptColumnRuleConfigurationYamlSwapper implements YamlSwapper<YamlEncryptColumnRuleConfiguration, EncryptColumnRuleConfiguration> {
@Override
public YamlEncryptColumnRuleConfiguration swap(final EncryptColumnRuleConfiguration data) {
YamlEncryptColumnRuleConfiguration result = new YamlEncryptColumnRuleConfiguration();
result.setPlainColumn(data.getPlainColumn());
result.setCipherColumn(data.getCipherColumn());
result.setAssistedQueryColumn(data.getAssistedQueryColumn());
result.setEncryptor(data.getEncryptor());
return result;
}
@Override
public EncryptColumnRuleConfiguration swap(final YamlEncryptColumnRuleConfiguration yamlConfiguration) {
return new EncryptColumnRuleConfiguration(
yamlConfiguration.getPlainColumn(), yamlConfiguration.getCipherColumn(), yamlConfiguration.getAssistedQueryColumn(), yamlConfiguration.getEncryptor());
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.yaml.swapper;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import org.apache.shardingsphere.encrypt.api.EncryptRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptTableRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptorRuleConfiguration;
import org.apache.shardingsphere.encrypt.yaml.config.YamlEncryptRuleConfiguration;
import org.apache.shardingsphere.encrypt.yaml.config.YamlEncryptTableRuleConfiguration;
import org.apache.shardingsphere.encrypt.yaml.config.YamlEncryptorRuleConfiguration;
import org.apache.shardingsphere.underlying.common.yaml.swapper.YamlSwapper;
/**
* Encrypt rule configuration yaml swapper.
*
* @author panjuan
*/
public final class EncryptRuleConfigurationYamlSwapper implements YamlSwapper<YamlEncryptRuleConfiguration, EncryptRuleConfiguration> {
private final EncryptorRuleConfigurationYamlSwapper encryptorRuleConfigurationYamlSwapper = new EncryptorRuleConfigurationYamlSwapper();
private final EncryptTableRuleConfigurationYamlSwapper encryptTableRuleConfigurationYamlSwapper = new EncryptTableRuleConfigurationYamlSwapper();
@Override
public YamlEncryptRuleConfiguration swap(final EncryptRuleConfiguration data) {
YamlEncryptRuleConfiguration result = new YamlEncryptRuleConfiguration();
result.getEncryptors().putAll(Maps.transformValues(data.getEncryptors(), new Function<EncryptorRuleConfiguration, YamlEncryptorRuleConfiguration>() {
@Override
public YamlEncryptorRuleConfiguration apply(final EncryptorRuleConfiguration input) {
return encryptorRuleConfigurationYamlSwapper.swap(input);
}
}));
result.getTables().putAll(Maps.transformValues(data.getTables(), new Function<EncryptTableRuleConfiguration, YamlEncryptTableRuleConfiguration>() {
@Override
public YamlEncryptTableRuleConfiguration apply(final EncryptTableRuleConfiguration input) {
return encryptTableRuleConfigurationYamlSwapper.swap(input);
}
}));
return result;
}
@Override
public EncryptRuleConfiguration swap(final YamlEncryptRuleConfiguration yamlConfiguration) {
EncryptRuleConfiguration result = new EncryptRuleConfiguration();
result.getEncryptors().putAll(Maps.transformValues(yamlConfiguration.getEncryptors(), new Function<YamlEncryptorRuleConfiguration, EncryptorRuleConfiguration>() {
@Override
public EncryptorRuleConfiguration apply(final YamlEncryptorRuleConfiguration input) {
return encryptorRuleConfigurationYamlSwapper.swap(input);
}
}));
result.getTables().putAll(Maps.transformValues(yamlConfiguration.getTables(), new Function<YamlEncryptTableRuleConfiguration, EncryptTableRuleConfiguration>() {
@Override
public EncryptTableRuleConfiguration apply(final YamlEncryptTableRuleConfiguration input) {
return encryptTableRuleConfigurationYamlSwapper.swap(input);
}
}));
return result;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.yaml.swapper;
import org.apache.shardingsphere.encrypt.api.EncryptColumnRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptTableRuleConfiguration;
import org.apache.shardingsphere.encrypt.yaml.config.YamlEncryptColumnRuleConfiguration;
import org.apache.shardingsphere.encrypt.yaml.config.YamlEncryptTableRuleConfiguration;
import org.apache.shardingsphere.underlying.common.yaml.swapper.YamlSwapper;
import java.util.Map.Entry;
/**
* Encrypt table configuration YAML swapper.
*
* @author panjuan
*/
public final class EncryptTableRuleConfigurationYamlSwapper implements YamlSwapper<YamlEncryptTableRuleConfiguration, EncryptTableRuleConfiguration> {
private final EncryptColumnRuleConfigurationYamlSwapper columnRuleConfigurationYamlSwapper = new EncryptColumnRuleConfigurationYamlSwapper();
@Override
public YamlEncryptTableRuleConfiguration swap(final EncryptTableRuleConfiguration data) {
YamlEncryptTableRuleConfiguration result = new YamlEncryptTableRuleConfiguration();
for (Entry<String, EncryptColumnRuleConfiguration> entry : data.getColumns().entrySet()) {
result.getColumns().put(entry.getKey(), columnRuleConfigurationYamlSwapper.swap(entry.getValue()));
}
return result;
}
@Override
public EncryptTableRuleConfiguration swap(final YamlEncryptTableRuleConfiguration yamlConfiguration) {
EncryptTableRuleConfiguration result = new EncryptTableRuleConfiguration();
for (Entry<String, YamlEncryptColumnRuleConfiguration> entry : yamlConfiguration.getColumns().entrySet()) {
result.getColumns().put(entry.getKey(), columnRuleConfigurationYamlSwapper.swap(entry.getValue()));
}
return result;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.yaml.swapper;
import org.apache.shardingsphere.encrypt.api.EncryptorRuleConfiguration;
import org.apache.shardingsphere.encrypt.yaml.config.YamlEncryptorRuleConfiguration;
import org.apache.shardingsphere.underlying.common.yaml.swapper.YamlSwapper;
/**
* Encryptor configuration YAML swapper.
*
* @author panjuan
*/
public final class EncryptorRuleConfigurationYamlSwapper implements YamlSwapper<YamlEncryptorRuleConfiguration, EncryptorRuleConfiguration> {
@Override
public YamlEncryptorRuleConfiguration swap(final EncryptorRuleConfiguration data) {
YamlEncryptorRuleConfiguration result = new YamlEncryptorRuleConfiguration();
result.setType(data.getType());
result.setProps(data.getProperties());
return result;
}
@Override
public EncryptorRuleConfiguration swap(final YamlEncryptorRuleConfiguration yamlConfiguration) {
return new EncryptorRuleConfiguration(yamlConfiguration.getType(), yamlConfiguration.getProps());
}
}
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
org.apache.shardingsphere.encrypt.strategy.impl.MD5Encryptor
org.apache.shardingsphere.encrypt.strategy.impl.AESEncryptor
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rule;
import org.apache.shardingsphere.encrypt.api.EncryptColumnRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptTableRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptorRuleConfiguration;
import org.junit.Before;
import org.junit.Test;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
public final class EncryptRuleTest {
private final String table = "table";
private final String column = "column";
private final String idNumber = "idNumber";
private EncryptRuleConfiguration encryptRuleConfig;
@Before
public void setUp() {
Properties props = new Properties();
EncryptColumnRuleConfiguration columnConfig = new EncryptColumnRuleConfiguration("plain_pwd", "cipher_pwd", "", "aes");
EncryptColumnRuleConfiguration idNumberConfig = new EncryptColumnRuleConfiguration("plain_id_number", "cipher_id_number", "", "aes");
Map<String, EncryptColumnRuleConfiguration> ruleConfigurationMap = new HashMap<>();
ruleConfigurationMap.put(column, columnConfig);
ruleConfigurationMap.put(idNumber, idNumberConfig);
EncryptorRuleConfiguration encryptorConfig = new EncryptorRuleConfiguration("assistedTest", props);
EncryptTableRuleConfiguration tableConfig = new EncryptTableRuleConfiguration(ruleConfigurationMap);
encryptRuleConfig = new EncryptRuleConfiguration();
encryptRuleConfig.getEncryptors().put("aes", encryptorConfig);
encryptRuleConfig.getTables().put(table, tableConfig);
}
@Test
public void assertGetEncryptAssistedQueryValues() {
List<Object> encryptAssistedQueryValues = new EncryptRule(encryptRuleConfig).getEncryptAssistedQueryValues(table, column, Collections.singletonList(null));
for (final Object value : encryptAssistedQueryValues) {
assertNull(value);
}
}
@Test
public void assertGetEncryptValues() {
List<Object> encryptAssistedQueryValues = new EncryptRule(encryptRuleConfig).getEncryptValues(table, column, Collections.singletonList(null));
for (final Object value : encryptAssistedQueryValues) {
assertNull(value);
}
}
@Test
public void assertFindEncryptTable() {
assertTrue(new EncryptRule(encryptRuleConfig).findEncryptTable(table).isPresent());
}
@Test
public void assertGetLogicColumnOfCipher() {
assertThat(new EncryptRule(encryptRuleConfig).getLogicColumnOfCipher(table, "cipher_pwd"), is(column));
}
@Test
public void assertFindPlainColumn() {
assertTrue(new EncryptRule(encryptRuleConfig).findPlainColumn(table, column).isPresent());
assertTrue(new EncryptRule(encryptRuleConfig).findPlainColumn(table, idNumber.toLowerCase()).isPresent());
assertFalse(new EncryptRule(encryptRuleConfig).findPlainColumn(table, "notExistLogicColumn").isPresent());
}
@Test(expected = NullPointerException.class)
public void assertGetCipherColumnWhenNoEncryptColumn() {
new EncryptRule(encryptRuleConfig).getCipherColumn(table, "cipher_pwd");
}
@Test
public void assertGetCipherColumnWhenEncryptColumnExist() {
assertThat(new EncryptRule(encryptRuleConfig).getCipherColumn(table, column), is("cipher_pwd"));
}
@Test
public void assertIsCipherColumn() {
assertTrue(new EncryptRule(encryptRuleConfig).isCipherColumn(table, "cipher_pwd"));
}
@Test
public void assertFindAssistedQueryColumn() {
assertFalse(new EncryptRule(encryptRuleConfig).findAssistedQueryColumn(table, "cipher_pwd").isPresent());
}
@Test
public void assertGetAssistedQueryColumns() {
assertTrue(new EncryptRule(encryptRuleConfig).getAssistedQueryColumns(table).isEmpty());
}
@Test
public void assertGetAssistedQueryAndPlainColumns() {
assertFalse(new EncryptRule(encryptRuleConfig).getAssistedQueryAndPlainColumns(table).isEmpty());
}
@Test
public void assertGetLogicAndCipherColumns() {
assertFalse(new EncryptRule(encryptRuleConfig).getLogicAndCipherColumns(table).isEmpty());
}
@Test
public void assertGetLogicAndPlainColumns() {
assertFalse(new EncryptRule(encryptRuleConfig).getLogicAndPlainColumns(table).isEmpty());
}
@Test
public void assertGetEncryptTableNames() {
assertFalse(new EncryptRule(encryptRuleConfig).getEncryptTableNames().isEmpty());
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.fixture;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.strategy.spi.Encryptor;
import java.util.Properties;
@Getter
@Setter
public final class TestEncryptor implements Encryptor {
private Properties properties = new Properties();
@Override
public String getType() {
return "test";
}
@Override
public void init() {
}
@Override
public String encrypt(final Object plaintext) {
return "encryptValue";
}
@Override
public Object decrypt(final String ciphertext) {
return "decryptValue";
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.fixture;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.strategy.spi.QueryAssistedEncryptor;
import java.util.Properties;
@Getter
@Setter
public final class TestQueryAssistedEncryptor implements QueryAssistedEncryptor {
private Properties properties = new Properties();
@Override
public String getType() {
return "assistedTest";
}
@Override
public void init() {
}
@Override
public String encrypt(final Object plaintext) {
return "encryptValue";
}
@Override
public Object decrypt(final String ciphertext) {
return "decryptValue";
}
@Override
public String queryAssistedEncrypt(final String plaintext) {
return "assistedEncryptValue";
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.impl;
import org.junit.Before;
import org.junit.Test;
import java.util.Properties;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
public final class AESEncryptorTest {
private final AESEncryptor encryptor = new AESEncryptor();
@Before
public void setUp() {
Properties properties = new Properties();
properties.setProperty("aes.key.value", "test");
encryptor.setProperties(properties);
}
@Test
public void assertGetType() {
assertThat(encryptor.getType(), is("AES"));
}
@Test
public void assertEncode() {
assertThat(encryptor.encrypt("test"), is("dSpPiyENQGDUXMKFMJPGWA=="));
}
@Test(expected = IllegalArgumentException.class)
public void assertEncodeWithoutKey() {
Properties properties = new Properties();
encryptor.setProperties(properties);
assertThat(encryptor.encrypt("test"), is("dSpPiyENQGDUXMKFMJPGWA=="));
}
@Test
public void assertDecode() {
assertThat(encryptor.decrypt("dSpPiyENQGDUXMKFMJPGWA==").toString(), is("test"));
}
@Test
public void assertDecodeWithNull() {
assertNull(encryptor.decrypt(null));
}
@Test(expected = IllegalArgumentException.class)
public void assertDecodeWithoutKey() {
Properties properties = new Properties();
encryptor.setProperties(properties);
assertThat(encryptor.decrypt("dSpPiyENQGDUXMKFMJPGWA==").toString(), is("test"));
}
@Test
public void assertGetProperties() {
assertThat(encryptor.getProperties().get("aes.key.value").toString(), is("test"));
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.impl;
import org.apache.shardingsphere.encrypt.strategy.EncryptColumn;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public final class EncryptColumnTest {
@Test
public void assertGetAssistedQueryColumn() {
assertTrue(new EncryptColumn("cipherColumn", "assistedQueryColumn", "plainColumn", "encryptor").getAssistedQueryColumn().isPresent());
}
@Test
public void assertGetPlainColumn() {
assertTrue(new EncryptColumn("cipherColumn", "assistedQueryColumn", "plainColumn", "encryptor").getPlainColumn().isPresent());
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.impl;
import com.google.common.collect.ImmutableMap;
import org.apache.shardingsphere.encrypt.api.EncryptColumnRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.EncryptTableRuleConfiguration;
import org.apache.shardingsphere.underlying.common.exception.ShardingSphereException;
import org.apache.shardingsphere.encrypt.strategy.EncryptTable;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public final class EncryptTableTest {
private EncryptTable encryptTable;
@Before
public void setUp() {
EncryptTableRuleConfiguration config = mock(EncryptTableRuleConfiguration.class);
EncryptColumnRuleConfiguration encryptColumnRuleConfiguration = mock(EncryptColumnRuleConfiguration.class);
when(config.getColumns()).thenReturn(ImmutableMap.of("key", encryptColumnRuleConfiguration));
when(encryptColumnRuleConfiguration.getCipherColumn()).thenReturn("cipherColumn");
when(encryptColumnRuleConfiguration.getAssistedQueryColumn()).thenReturn("assistedQueryColumn");
when(encryptColumnRuleConfiguration.getPlainColumn()).thenReturn("plainColumn");
when(encryptColumnRuleConfiguration.getEncryptor()).thenReturn("encryptor");
encryptTable = new EncryptTable(config);
}
@Test
public void assertGetLogicColumnOfCipher() {
assertNotNull(encryptTable.getLogicColumnOfCipher("cipherColumn"));
}
@Test(expected = ShardingSphereException.class)
public void assertGetLogicColumnShardingExceptionThrownWhenCipherColumnAbsent() {
encryptTable.getLogicColumnOfCipher("___cipherColumn");
}
@Test
public void assertGetLogicColumns() {
assertFalse(encryptTable.getLogicColumns().isEmpty());
}
@Test
public void assertFindPlainColumn() {
assertFalse(encryptTable.findPlainColumn("logicColumn").isPresent());
}
@Test
public void assertGetLogicAndCipherColumns() {
assertFalse(encryptTable.getLogicAndCipherColumns().isEmpty());
}
@Test
public void assertGetLogicAndPlainColumns() {
assertFalse(encryptTable.getLogicAndPlainColumns().isEmpty());
}
@Test
public void assertGetEncryptor() {
assertTrue(encryptTable.findEncryptor("key").isPresent());
assertFalse(encryptTable.findEncryptor("notExistLogicColumn").isPresent());
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.impl;
import org.junit.Test;
import java.util.Properties;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public final class MD5EncryptorTest {
private final MD5Encryptor encryptor = new MD5Encryptor();
@Test
public void assertGetType() {
assertThat(encryptor.getType(), is("MD5"));
}
@Test
public void assertEncode() {
assertThat(encryptor.encrypt("test"), is("098f6bcd4621d373cade4e832627b4f6"));
}
@Test
public void assertDecode() {
assertThat(encryptor.decrypt("test").toString(), is("test"));
}
@Test
public void assertProperties() {
Properties properties = new Properties();
properties.setProperty("key1", "value1");
encryptor.setProperties(properties);
assertThat(encryptor.getProperties().get("key1").toString(), is("value1"));
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.strategy.spi.loader;
import org.apache.shardingsphere.encrypt.strategy.fixture.TestEncryptor;
import org.apache.shardingsphere.encrypt.strategy.impl.AESEncryptor;
import org.apache.shardingsphere.encrypt.strategy.impl.MD5Encryptor;
import org.junit.Test;
import java.util.Properties;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertThat;
public final class EncryptorServiceLoaderTest {
private EncryptorServiceLoader serviceLoader = new EncryptorServiceLoader();
@Test
public void assertNewMD5Encryptor() {
assertThat(serviceLoader.newService("MD5", new Properties()), instanceOf(MD5Encryptor.class));
}
@Test
public void assertNewAESEncryptor() {
assertThat(serviceLoader.newService("AES", new Properties()), instanceOf(AESEncryptor.class));
}
@Test
public void assertNewDefaultEncryptor() {
assertThat(serviceLoader.newService(), instanceOf(TestEncryptor.class));
}
}
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
org.apache.shardingsphere.encrypt.strategy.fixture.TestEncryptor
org.apache.shardingsphere.encrypt.strategy.fixture.TestQueryAssistedEncryptor
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>encrypt-core</artifactId>
<version>5.0.0-RC1-SNAPSHOT</version>
</parent>
<artifactId>encrypt-core-merge</artifactId>
<name>${project.artifactId}</name>
<dependencies>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-merge</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>encrypt-core-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.merge;
import org.apache.shardingsphere.encrypt.merge.dal.EncryptDALResultDecorator;
import org.apache.shardingsphere.encrypt.merge.dql.EncryptDQLResultDecorator;
import org.apache.shardingsphere.encrypt.merge.dql.EncryptorMetaData;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.spi.database.type.DatabaseType;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.SelectSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.statement.dal.DALStatement;
import org.apache.shardingsphere.underlying.common.constant.properties.PropertiesConstant;
import org.apache.shardingsphere.underlying.common.constant.properties.ShardingSphereProperties;
import org.apache.shardingsphere.underlying.merge.engine.decorator.ResultDecorator;
import org.apache.shardingsphere.underlying.merge.engine.decorator.impl.TransparentResultDecorator;
import org.apache.shardingsphere.underlying.merge.engine.decorator.ResultDecoratorEngine;
/**
* Result decorator engine for encrypt.
*
* @author zhangliang
* @author panjuan
*/
public abstract class EncryptResultDecoratorEngine implements ResultDecoratorEngine<EncryptRule> {
@Override
public final ResultDecorator newInstance(final DatabaseType databaseType,
final EncryptRule encryptRule, final ShardingSphereProperties properties, final SQLStatementContext sqlStatementContext) {
if (sqlStatementContext instanceof SelectSQLStatementContext) {
return new EncryptDQLResultDecorator(createEncryptorMetaData(encryptRule, sqlStatementContext), properties.<Boolean>getValue(PropertiesConstant.QUERY_WITH_CIPHER_COLUMN));
}
if (sqlStatementContext.getSqlStatement() instanceof DALStatement) {
return new EncryptDALResultDecorator(encryptRule);
}
return new TransparentResultDecorator();
}
protected abstract EncryptorMetaData createEncryptorMetaData(EncryptRule encryptRule, SQLStatementContext sqlStatementContext);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.merge.dal;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.encrypt.merge.dal.impl.DecoratedDescribeTableMergedResult;
import org.apache.shardingsphere.encrypt.merge.dal.impl.MergedDescribeTableMergedResult;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dal.dialect.mysql.DescribeStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dal.dialect.mysql.ShowColumnsStatement;
import org.apache.shardingsphere.underlying.executor.QueryResult;
import org.apache.shardingsphere.underlying.merge.engine.decorator.ResultDecorator;
import org.apache.shardingsphere.underlying.merge.result.MergedResult;
import org.apache.shardingsphere.underlying.merge.result.impl.transparent.TransparentMergedResult;
/**
* DAL result decorator for encrypt.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptDALResultDecorator implements ResultDecorator {
private final EncryptRule encryptRule;
@Override
public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext sqlStatementContext, final RelationMetas relationMetas) {
SQLStatement dalStatement = sqlStatementContext.getSqlStatement();
if (dalStatement instanceof DescribeStatement || dalStatement instanceof ShowColumnsStatement) {
return new MergedDescribeTableMergedResult(queryResult, sqlStatementContext, encryptRule);
}
return new TransparentMergedResult(queryResult);
}
@Override
public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext sqlStatementContext, final RelationMetas relationMetas) {
SQLStatement dalStatement = sqlStatementContext.getSqlStatement();
if (dalStatement instanceof DescribeStatement || dalStatement instanceof ShowColumnsStatement) {
return new DecoratedDescribeTableMergedResult(mergedResult, sqlStatementContext, encryptRule);
}
return mergedResult;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.merge.dal.impl;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.underlying.merge.result.MergedResult;
import java.sql.SQLException;
/**
* Decorated merged result for describe table.
*
* @author zhangliang
*/
public final class DecoratedDescribeTableMergedResult extends DescribeTableMergedResult {
private final MergedResult mergedResult;
public DecoratedDescribeTableMergedResult(final MergedResult mergedResult, final SQLStatementContext sqlStatementContext, final EncryptRule encryptRule) {
super(sqlStatementContext, encryptRule);
this.mergedResult = mergedResult;
}
@Override
protected boolean nextValue() throws SQLException {
return mergedResult.next();
}
@Override
protected Object getOriginalValue(final int columnIndex, final Class<?> type) throws SQLException {
return mergedResult.getValue(columnIndex, type);
}
@Override
public boolean wasNull() throws SQLException {
return mergedResult.wasNull();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.merge.dal.impl;
import com.google.common.base.Optional;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.encrypt.strategy.EncryptTable;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.underlying.merge.result.MergedResult;
import java.io.InputStream;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Calendar;
/**
* Merged result for describe table.
*
* @author liya
*/
public abstract class DescribeTableMergedResult implements MergedResult {
private final EncryptRule encryptRule;
private final SQLStatementContext sqlStatementContext;
protected DescribeTableMergedResult(final SQLStatementContext sqlStatementContext, final EncryptRule encryptRule) {
this.encryptRule = encryptRule;
this.sqlStatementContext = sqlStatementContext;
}
@Override
public final boolean next() throws SQLException {
Optional<EncryptTable> encryptTable = encryptRule.findEncryptTable(sqlStatementContext.getTablesContext().getSingleTableName());
boolean hasNext = nextValue();
if (hasNext && !encryptTable.isPresent()) {
return true;
}
if (!hasNext) {
return false;
}
String columnName = getOriginalValue(1, String.class).toString();
while (encryptTable.get().getAssistedQueryColumns().contains(columnName) || encryptTable.get().getPlainColumns().contains(columnName)) {
hasNext = nextValue();
if (!hasNext) {
return false;
}
}
return true;
}
@Override
public final Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
if (1 == columnIndex) {
String columnName = getOriginalValue(columnIndex, type).toString();
Optional<EncryptTable> encryptTable = encryptRule.findEncryptTable(sqlStatementContext.getTablesContext().getSingleTableName());
if (encryptTable.isPresent() && encryptTable.get().getCipherColumns().contains(columnName)) {
return encryptTable.get().getLogicColumnOfCipher(columnName);
}
return columnName;
}
return getOriginalValue(columnIndex, type);
}
@Override
public final Object getCalendarValue(final int columnIndex, final Class<?> type, final Calendar calendar) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@SuppressWarnings("deprecation")
@Override
public final InputStream getInputStream(final int columnIndex, final String type) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
protected abstract boolean nextValue() throws SQLException;
protected abstract Object getOriginalValue(int columnIndex, Class<?> type) throws SQLException;
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.merge.dal.impl;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.underlying.executor.QueryResult;
import java.sql.SQLException;
/**
* Merged merged result for describe table.
*
* @author liya
*/
public final class MergedDescribeTableMergedResult extends DescribeTableMergedResult {
private final QueryResult queryResult;
public MergedDescribeTableMergedResult(final QueryResult queryResult, final SQLStatementContext sqlStatementContext, final EncryptRule encryptRule) {
super(sqlStatementContext, encryptRule);
this.queryResult = queryResult;
}
@Override
protected boolean nextValue() throws SQLException {
return queryResult.next();
}
@Override
protected Object getOriginalValue(final int columnIndex, final Class<?> type) throws SQLException {
return queryResult.getValue(columnIndex, type);
}
@Override
public boolean wasNull() throws SQLException {
return queryResult.wasNull();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.merge.dql;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.underlying.executor.QueryResult;
import org.apache.shardingsphere.underlying.merge.engine.decorator.ResultDecorator;
import org.apache.shardingsphere.underlying.merge.result.MergedResult;
import org.apache.shardingsphere.underlying.merge.result.impl.transparent.TransparentMergedResult;
/**
* DQL result decorator for encrypt.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptDQLResultDecorator implements ResultDecorator {
private final EncryptorMetaData encryptorMetaData;
private final boolean queryWithCipherColumn;
@Override
public MergedResult decorate(final QueryResult queryResult, final SQLStatementContext sqlStatementContext, final RelationMetas relationMetas) {
return new EncryptMergedResult(encryptorMetaData, new TransparentMergedResult(queryResult), queryWithCipherColumn);
}
@Override
public MergedResult decorate(final MergedResult mergedResult, final SQLStatementContext sqlStatementContext, final RelationMetas relationMetas) {
return new EncryptMergedResult(encryptorMetaData, mergedResult, queryWithCipherColumn);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.merge.dql;
import com.google.common.base.Optional;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.underlying.merge.result.MergedResult;
import org.apache.shardingsphere.encrypt.strategy.spi.Encryptor;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.Calendar;
/**
* Merged result for encrypt.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptMergedResult implements MergedResult {
private final EncryptorMetaData metaData;
private final MergedResult mergedResult;
private final boolean queryWithCipherColumn;
@Override
public boolean next() throws SQLException {
return mergedResult.next();
}
@Override
public Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
if (!queryWithCipherColumn) {
return mergedResult.getValue(columnIndex, type);
}
Optional<Encryptor> encryptor = metaData.findEncryptor(columnIndex);
if (!encryptor.isPresent()) {
return mergedResult.getValue(columnIndex, type);
}
String ciphertext = (String) mergedResult.getValue(columnIndex, String.class);
return null == ciphertext ? null : encryptor.get().decrypt(ciphertext);
}
@Override
public Object getCalendarValue(final int columnIndex, final Class<?> type, final Calendar calendar) throws SQLException {
return mergedResult.getCalendarValue(columnIndex, type, calendar);
}
@Override
public InputStream getInputStream(final int columnIndex, final String type) throws SQLException {
return mergedResult.getInputStream(columnIndex, type);
}
@Override
public boolean wasNull() throws SQLException {
return mergedResult.wasNull();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.merge.dql;
import com.google.common.base.Optional;
import org.apache.shardingsphere.encrypt.strategy.spi.Encryptor;
import java.sql.SQLException;
/**
* Encryptor meta data.
*
* @author zhangliang
*/
public interface EncryptorMetaData {
/**
* Find encryptor.
*
* @param columnIndex column index
* @return encryptor
* @throws SQLException SQL exception
*/
Optional<Encryptor> findEncryptor(int columnIndex) throws SQLException;
}
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>encrypt-core</artifactId>
<version>5.0.0-RC1-SNAPSHOT</version>
</parent>
<artifactId>encrypt-core-rewrite</artifactId>
<name>${project.artifactId}</name>
<dependencies>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-relation</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-rewrite-engine</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-rewrite-test</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-sql92</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-mysql</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-postgresql</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-oracle</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-parser-sqlserver</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java7</artifactId>
</dependency>
</dependencies>
</project>
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.aware;
/**
* Query with cipher column aware.
*
* @author zhangliang
*/
public interface QueryWithCipherColumnAware {
/**
* Set is query with cipher column or not.
*
* @param queryWithCipherColumn is query with cipher column or not
*/
void setQueryWithCipherColumn(boolean queryWithCipherColumn);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.condition;
import java.util.List;
import java.util.Map;
/**
* Encrypt condition.
*
* @author zhangliang
*/
public interface EncryptCondition {
/**
* Get column name.
*
* @return column name
*/
String getColumnName();
/**
* Get table name.
*
* @return table name
*/
String getTableName();
/**
* Get start index.
*
* @return start index
*/
int getStartIndex();
/**
* Get stop index.
*
* @return stop index
*/
int getStopIndex();
/**
* Get position index map.
*
* @return position index map
*/
Map<Integer, Integer> getPositionIndexMap();
/**
* Get position value map.
*
* @return position value map
*/
Map<Integer, Object> getPositionValueMap();
/**
* Get values.
*
* @param parameters SQL parameters
* @return values
*/
List<Object> getValues(List<Object> parameters);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.condition;
import com.google.common.base.Optional;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.encrypt.rewrite.condition.impl.EncryptEqualCondition;
import org.apache.shardingsphere.encrypt.rewrite.condition.impl.EncryptInCondition;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.sql.parser.relation.segment.table.TablesContext;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.SimpleExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.AndPredicate;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.PredicateSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.SubqueryPredicateSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.WhereSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.value.PredicateBetweenRightValue;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.value.PredicateCompareRightValue;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.value.PredicateInRightValue;
import org.apache.shardingsphere.sql.parser.sql.statement.generic.WhereSegmentAvailable;
import org.apache.shardingsphere.underlying.common.exception.ShardingSphereException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
/**
* Encrypt condition engine.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptConditionEngine {
private final EncryptRule encryptRule;
private final RelationMetas relationMetas;
/**
* Create encrypt conditions.
*
* @param sqlStatementContext SQL statement context
* @return encrypt conditions
*/
public List<EncryptCondition> createEncryptConditions(final SQLStatementContext sqlStatementContext) {
if (!(sqlStatementContext.getSqlStatement() instanceof WhereSegmentAvailable)) {
return Collections.emptyList();
}
Optional<WhereSegment> whereSegment = ((WhereSegmentAvailable) sqlStatementContext.getSqlStatement()).getWhere();
if (!whereSegment.isPresent()) {
return Collections.emptyList();
}
List<EncryptCondition> result = new LinkedList<>();
for (AndPredicate each : whereSegment.get().getAndPredicates()) {
result.addAll(createEncryptConditions(each, sqlStatementContext.getTablesContext()));
}
for (SubqueryPredicateSegment each : sqlStatementContext.getSqlStatement().findSQLSegments(SubqueryPredicateSegment.class)) {
for (AndPredicate andPredicate : each.getAndPredicates()) {
result.addAll(createEncryptConditions(andPredicate, sqlStatementContext.getTablesContext()));
}
}
return result;
}
private Collection<EncryptCondition> createEncryptConditions(final AndPredicate andPredicate, final TablesContext tablesContext) {
Collection<EncryptCondition> result = new LinkedList<>();
Collection<Integer> stopIndexes = new HashSet<>();
for (PredicateSegment predicate : andPredicate.getPredicates()) {
if (stopIndexes.add(predicate.getStopIndex())) {
Optional<EncryptCondition> condition = createEncryptCondition(predicate, tablesContext);
if (condition.isPresent()) {
result.add(condition.get());
}
}
}
return result;
}
private Optional<EncryptCondition> createEncryptCondition(final PredicateSegment predicateSegment, final TablesContext tablesContext) {
Optional<String> tableName = tablesContext.findTableName(predicateSegment.getColumn(), relationMetas);
return tableName.isPresent() && encryptRule.findEncryptor(tableName.get(), predicateSegment.getColumn().getName()).isPresent()
? createEncryptCondition(predicateSegment, tableName.get()) : Optional.<EncryptCondition>absent();
}
private Optional<EncryptCondition> createEncryptCondition(final PredicateSegment predicateSegment, final String tableName) {
if (predicateSegment.getRightValue() instanceof PredicateCompareRightValue) {
PredicateCompareRightValue compareRightValue = (PredicateCompareRightValue) predicateSegment.getRightValue();
return isSupportedOperator(compareRightValue.getOperator()) ? createCompareEncryptCondition(tableName, predicateSegment, compareRightValue) : Optional.<EncryptCondition>absent();
}
if (predicateSegment.getRightValue() instanceof PredicateInRightValue) {
return createInEncryptCondition(tableName, predicateSegment, (PredicateInRightValue) predicateSegment.getRightValue());
}
if (predicateSegment.getRightValue() instanceof PredicateBetweenRightValue) {
throw new ShardingSphereException("The SQL clause 'BETWEEN...AND...' is unsupported in encrypt rule.");
}
return Optional.absent();
}
private static Optional<EncryptCondition> createCompareEncryptCondition(final String tableName, final PredicateSegment predicateSegment, final PredicateCompareRightValue compareRightValue) {
return compareRightValue.getExpression() instanceof SimpleExpressionSegment
? Optional.<EncryptCondition>of(new EncryptEqualCondition(predicateSegment.getColumn().getName(), tableName, compareRightValue.getExpression().getStartIndex(),
predicateSegment.getStopIndex(), compareRightValue.getExpression()))
: Optional.<EncryptCondition>absent();
}
private static Optional<EncryptCondition> createInEncryptCondition(final String tableName, final PredicateSegment predicateSegment, final PredicateInRightValue inRightValue) {
List<ExpressionSegment> expressionSegments = new LinkedList<>();
for (ExpressionSegment each : inRightValue.getSqlExpressions()) {
if (each instanceof SimpleExpressionSegment) {
expressionSegments.add(each);
}
}
return expressionSegments.isEmpty() ? Optional.<EncryptCondition>absent()
: Optional.<EncryptCondition>of(new EncryptInCondition(
predicateSegment.getColumn().getName(), tableName, inRightValue.getSqlExpressions().iterator().next().getStartIndex(), predicateSegment.getStopIndex(), expressionSegments));
}
private boolean isSupportedOperator(final String operator) {
return "=".equals(operator) || "<>".equals(operator) || "!=".equals(operator);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.condition.impl;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import org.apache.shardingsphere.encrypt.rewrite.condition.EncryptCondition;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Encrypt condition for equal.
*
* @author zhangliang
* @author maxiaoguang
*/
@Getter
@EqualsAndHashCode
@ToString
public final class EncryptEqualCondition implements EncryptCondition {
private final String columnName;
private final String tableName;
private final int startIndex;
private final int stopIndex;
private final Map<Integer, Integer> positionIndexMap = new LinkedHashMap<>();
private final Map<Integer, Object> positionValueMap = new LinkedHashMap<>();
public EncryptEqualCondition(final String columnName, final String tableName, final int startIndex, final int stopIndex, final ExpressionSegment expressionSegment) {
this.columnName = columnName;
this.tableName = tableName;
this.startIndex = startIndex;
this.stopIndex = stopIndex;
putPositionMap(expressionSegment);
}
private void putPositionMap(final ExpressionSegment expressionSegment) {
if (expressionSegment instanceof ParameterMarkerExpressionSegment) {
positionIndexMap.put(0, ((ParameterMarkerExpressionSegment) expressionSegment).getParameterMarkerIndex());
} else if (expressionSegment instanceof LiteralExpressionSegment) {
positionValueMap.put(0, ((LiteralExpressionSegment) expressionSegment).getLiterals());
}
}
/**
* Get values.
*
* @param parameters SQL parameters
* @return values
*/
public List<Object> getValues(final List<Object> parameters) {
List<Object> result = new ArrayList<>(positionValueMap.values());
for (Entry<Integer, Integer> entry : positionIndexMap.entrySet()) {
Object parameter = parameters.get(entry.getValue());
if (entry.getKey() < result.size()) {
result.add(entry.getKey(), parameter);
} else {
result.add(parameter);
}
}
return result;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.condition.impl;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import org.apache.shardingsphere.encrypt.rewrite.condition.EncryptCondition;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Encrypt condition.
*
* @author zhangliang
* @author maxiaoguang
*/
@Getter
@EqualsAndHashCode
@ToString
public final class EncryptInCondition implements EncryptCondition {
private final String columnName;
private final String tableName;
private final int startIndex;
private final int stopIndex;
private final Map<Integer, Integer> positionIndexMap = new LinkedHashMap<>();
private final Map<Integer, Object> positionValueMap = new LinkedHashMap<>();
public EncryptInCondition(final String columnName, final String tableName, final int startIndex, final int stopIndex, final List<ExpressionSegment> expressionSegments) {
this.columnName = columnName;
this.tableName = tableName;
this.startIndex = startIndex;
this.stopIndex = stopIndex;
int count = 0;
for (ExpressionSegment each : expressionSegments) {
putPositionMap(count, each);
count++;
}
}
private void putPositionMap(final int position, final ExpressionSegment expressionSegment) {
if (expressionSegment instanceof ParameterMarkerExpressionSegment) {
positionIndexMap.put(position, ((ParameterMarkerExpressionSegment) expressionSegment).getParameterMarkerIndex());
} else if (expressionSegment instanceof LiteralExpressionSegment) {
positionValueMap.put(position, ((LiteralExpressionSegment) expressionSegment).getLiterals());
}
}
@Override
public List<Object> getValues(final List<Object> parameters) {
List<Object> result = new ArrayList<>(positionValueMap.values());
for (Entry<Integer, Integer> entry : positionIndexMap.entrySet()) {
Object parameter = parameters.get(entry.getValue());
if (entry.getKey() < result.size()) {
result.add(entry.getKey(), parameter);
} else {
result.add(parameter);
}
}
return result;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.context;
import org.apache.shardingsphere.encrypt.rewrite.parameter.EncryptParameterRewriterBuilder;
import org.apache.shardingsphere.encrypt.rewrite.token.EncryptTokenGenerateBuilder;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.underlying.common.constant.properties.PropertiesConstant;
import org.apache.shardingsphere.underlying.common.constant.properties.ShardingSphereProperties;
import org.apache.shardingsphere.underlying.rewrite.context.SQLRewriteContext;
import org.apache.shardingsphere.underlying.rewrite.context.SQLRewriteContextDecorator;
import org.apache.shardingsphere.underlying.rewrite.parameter.rewriter.ParameterRewriter;
/**
* SQL rewrite context decorator for encrypt.
*
* @author zhangliang
*/
public final class EncryptSQLRewriteContextDecorator implements SQLRewriteContextDecorator<EncryptRule> {
@Override
public void decorate(final EncryptRule encryptRule, final ShardingSphereProperties properties, final SQLRewriteContext sqlRewriteContext) {
boolean isQueryWithCipherColumn = properties.<Boolean>getValue(PropertiesConstant.QUERY_WITH_CIPHER_COLUMN);
for (ParameterRewriter each : new EncryptParameterRewriterBuilder(encryptRule, isQueryWithCipherColumn).getParameterRewriters(sqlRewriteContext.getRelationMetas())) {
if (!sqlRewriteContext.getParameters().isEmpty() && each.isNeedRewrite(sqlRewriteContext.getSqlStatementContext())) {
each.rewrite(sqlRewriteContext.getParameterBuilder(), sqlRewriteContext.getSqlStatementContext(), sqlRewriteContext.getParameters());
}
}
sqlRewriteContext.addSQLTokenGenerators(new EncryptTokenGenerateBuilder(encryptRule, isQueryWithCipherColumn).getSQLTokenGenerators());
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.encrypt.rule.aware.EncryptRuleAware;
import org.apache.shardingsphere.underlying.rewrite.parameter.rewriter.ParameterRewriter;
/**
* Parameter rewriter for encrypt.
*
* @author zhangliang
*/
@Getter
@Setter
public abstract class EncryptParameterRewriter implements ParameterRewriter, EncryptRuleAware {
private EncryptRule encryptRule;
@Override
public final boolean isNeedRewrite(final SQLStatementContext sqlStatementContext) {
return isNeedRewriteForEncrypt(sqlStatementContext) && isNeedEncrypt(sqlStatementContext);
}
protected abstract boolean isNeedRewriteForEncrypt(SQLStatementContext sqlStatementContext);
private boolean isNeedEncrypt(final SQLStatementContext sqlStatementContext) {
for (String each : sqlStatementContext.getTablesContext().getTableNames()) {
if (encryptRule.findEncryptTable(each).isPresent()) {
return true;
}
}
return false;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
import org.apache.shardingsphere.encrypt.rewrite.parameter.impl.EncryptAssignmentParameterRewriter;
import org.apache.shardingsphere.encrypt.rewrite.parameter.impl.EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter;
import org.apache.shardingsphere.encrypt.rewrite.parameter.impl.EncryptInsertValueParameterRewriter;
import org.apache.shardingsphere.encrypt.rewrite.parameter.impl.EncryptPredicateParameterRewriter;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.encrypt.rule.aware.EncryptRuleAware;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.underlying.rewrite.parameter.rewriter.ParameterRewriter;
import org.apache.shardingsphere.underlying.rewrite.parameter.rewriter.ParameterRewriterBuilder;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.aware.RelationMetasAware;
import java.util.Collection;
import java.util.LinkedList;
/**
* Parameter rewriter builder for encrypt.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptParameterRewriterBuilder implements ParameterRewriterBuilder {
private final EncryptRule encryptRule;
private final boolean queryWithCipherColumn;
@Override
public Collection<ParameterRewriter> getParameterRewriters(final RelationMetas relationMetas) {
Collection<ParameterRewriter> result = getParameterRewriters();
for (ParameterRewriter each : result) {
setUpParameterRewriters(each, relationMetas);
}
return result;
}
private Collection<ParameterRewriter> getParameterRewriters() {
Collection<ParameterRewriter> result = new LinkedList<>();
result.add(new EncryptAssignmentParameterRewriter());
result.add(new EncryptPredicateParameterRewriter());
result.add(new EncryptInsertValueParameterRewriter());
result.add(new EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter());
return result;
}
private void setUpParameterRewriters(final ParameterRewriter parameterRewriter, final RelationMetas relationMetas) {
if (parameterRewriter instanceof RelationMetasAware) {
((RelationMetasAware) parameterRewriter).setRelationMetas(relationMetas);
}
if (parameterRewriter instanceof EncryptRuleAware) {
((EncryptRuleAware) parameterRewriter).setEncryptRule(encryptRule);
}
if (parameterRewriter instanceof QueryWithCipherColumnAware) {
((QueryWithCipherColumnAware) parameterRewriter).setQueryWithCipherColumn(queryWithCipherColumn);
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.apache.shardingsphere.encrypt.rewrite.parameter.EncryptParameterRewriter;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.UpdateStatement;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.ParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.GroupedParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.StandardParameterBuilder;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* Assignment parameter rewriter for encrypt.
*
* @author zhangliang
*/
public final class EncryptAssignmentParameterRewriter extends EncryptParameterRewriter {
@Override
protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext.getSqlStatement() instanceof UpdateStatement
|| sqlStatementContext instanceof InsertSQLStatementContext && sqlStatementContext.getSqlStatement().findSQLSegment(SetAssignmentSegment.class).isPresent();
}
@Override
public void rewrite(final ParameterBuilder parameterBuilder, final SQLStatementContext sqlStatementContext, final List<Object> parameters) {
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
for (AssignmentSegment each : getSetAssignmentSegment(sqlStatementContext.getSqlStatement()).getAssignments()) {
if (each.getValue() instanceof ParameterMarkerExpressionSegment && getEncryptRule().findEncryptor(tableName, each.getColumn().getName()).isPresent()) {
StandardParameterBuilder standardParameterBuilder = parameterBuilder instanceof StandardParameterBuilder
? (StandardParameterBuilder) parameterBuilder : ((GroupedParameterBuilder) parameterBuilder).getParameterBuilders().get(0);
encryptParameters(standardParameterBuilder, tableName, each, parameters);
}
}
}
private SetAssignmentSegment getSetAssignmentSegment(final SQLStatement sqlStatement) {
if (sqlStatement instanceof InsertStatement) {
Optional<SetAssignmentSegment> result = ((InsertStatement) sqlStatement).getSetAssignment();
Preconditions.checkState(result.isPresent());
return result.get();
}
return ((UpdateStatement) sqlStatement).getSetAssignment();
}
private void encryptParameters(final StandardParameterBuilder parameterBuilder, final String tableName, final AssignmentSegment assignmentSegment, final List<Object> parameters) {
String columnName = assignmentSegment.getColumn().getName();
int parameterMarkerIndex = ((ParameterMarkerExpressionSegment) assignmentSegment.getValue()).getParameterMarkerIndex();
Object originalValue = parameters.get(parameterMarkerIndex);
Object cipherValue = getEncryptRule().getEncryptValues(tableName, columnName, Collections.singletonList(originalValue)).iterator().next();
parameterBuilder.addReplacedParameters(parameterMarkerIndex, cipherValue);
Collection<Object> addedParameters = new LinkedList<>();
if (getEncryptRule().findAssistedQueryColumn(tableName, columnName).isPresent()) {
Object assistedQueryValue = getEncryptRule().getEncryptAssistedQueryValues(tableName, columnName, Collections.singletonList(originalValue)).iterator().next();
addedParameters.add(assistedQueryValue);
}
if (getEncryptRule().findPlainColumn(tableName, columnName).isPresent()) {
addedParameters.add(originalValue);
}
if (!addedParameters.isEmpty()) {
parameterBuilder.addAddedParameters(parameterMarkerIndex + 1, addedParameters);
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter.impl;
import com.google.common.base.Optional;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
import org.apache.shardingsphere.encrypt.rewrite.parameter.EncryptParameterRewriter;
import org.apache.shardingsphere.encrypt.strategy.spi.Encryptor;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.OnDuplicateKeyColumnsSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.ParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.GroupedParameterBuilder;
import java.util.Collection;
import java.util.List;
/**
* Insert on duplicate key update parameter rewriter for encrypt.
*
* @author chun.yang
*/
@Setter
public final class EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter extends EncryptParameterRewriter implements QueryWithCipherColumnAware {
private boolean queryWithCipherColumn;
@Override
protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext instanceof InsertSQLStatementContext && sqlStatementContext.getSqlStatement().findSQLSegment(OnDuplicateKeyColumnsSegment.class).isPresent();
}
@Override
public void rewrite(final ParameterBuilder parameterBuilder, final SQLStatementContext sqlStatementContext, final List<Object> parameters) {
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
OnDuplicateKeyColumnsSegment onDuplicateKeyColumnsSegment = sqlStatementContext.getSqlStatement().findSQLSegment(OnDuplicateKeyColumnsSegment.class).get();
Collection<AssignmentSegment> onDuplicateKeyColumnsSegments = onDuplicateKeyColumnsSegment.getColumns();
if (onDuplicateKeyColumnsSegments.isEmpty()) {
return;
}
GroupedParameterBuilder groupedParameterBuilder = (GroupedParameterBuilder) parameterBuilder;
for (AssignmentSegment each : onDuplicateKeyColumnsSegments) {
ExpressionSegment expressionSegment = each.getValue();
Object cipherColumnValue = null;
Object plainColumnValue = null;
if (expressionSegment instanceof ParameterMarkerExpressionSegment) {
plainColumnValue = parameters.get(((ParameterMarkerExpressionSegment) expressionSegment).getParameterMarkerIndex());
}
if (queryWithCipherColumn) {
Optional<Encryptor> encryptor = getEncryptRule().findEncryptor(tableName, each.getColumn().getName());
if (encryptor.isPresent()) {
cipherColumnValue = encryptor.get().encrypt(plainColumnValue);
groupedParameterBuilder.getOnDuplicateKeyUpdateAddedParameters().add(cipherColumnValue);
}
}
if (null != plainColumnValue) {
groupedParameterBuilder.getOnDuplicateKeyUpdateAddedParameters().add(plainColumnValue);
}
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.apache.shardingsphere.encrypt.rewrite.parameter.EncryptParameterRewriter;
import org.apache.shardingsphere.encrypt.strategy.spi.Encryptor;
import org.apache.shardingsphere.encrypt.strategy.spi.QueryAssistedEncryptor;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.ParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.GroupedParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.StandardParameterBuilder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* Insert value parameter rewriter for encrypt.
*
* @author zhangliang
*/
public final class EncryptInsertValueParameterRewriter extends EncryptParameterRewriter {
@Override
protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext instanceof InsertSQLStatementContext && !((InsertStatement) sqlStatementContext.getSqlStatement()).getSetAssignment().isPresent();
}
@Override
public void rewrite(final ParameterBuilder parameterBuilder, final SQLStatementContext sqlStatementContext, final List<Object> parameters) {
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
Iterator<String> descendingColumnNames = ((InsertSQLStatementContext) sqlStatementContext).getDescendingColumnNames();
while (descendingColumnNames.hasNext()) {
String columnName = descendingColumnNames.next();
Optional<Encryptor> encryptor = getEncryptRule().findEncryptor(tableName, columnName);
if (encryptor.isPresent()) {
encryptInsertValues((GroupedParameterBuilder) parameterBuilder, (InsertSQLStatementContext) sqlStatementContext, encryptor.get(), tableName, columnName);
}
}
}
private void encryptInsertValues(final GroupedParameterBuilder parameterBuilder,
final InsertSQLStatementContext sqlStatementContext, final Encryptor encryptor, final String tableName, final String encryptLogicColumnName) {
int columnIndex = getColumnIndex(parameterBuilder, sqlStatementContext, encryptLogicColumnName);
int count = 0;
for (List<Object> each : sqlStatementContext.getGroupedParameters()) {
if (!each.isEmpty()) {
StandardParameterBuilder standardParameterBuilder = parameterBuilder.getParameterBuilders().get(count);
encryptInsertValue(
encryptor, tableName, columnIndex, sqlStatementContext.getInsertValueContexts().get(count).getValue(columnIndex), standardParameterBuilder, encryptLogicColumnName);
}
count++;
}
}
private int getColumnIndex(final GroupedParameterBuilder parameterBuilder, final InsertSQLStatementContext sqlStatementContext, final String encryptLogicColumnName) {
List<String> columnNames;
if (parameterBuilder.getDerivedColumnName().isPresent()) {
columnNames = new ArrayList<>(sqlStatementContext.getColumnNames());
columnNames.remove(parameterBuilder.getDerivedColumnName().get());
} else {
columnNames = sqlStatementContext.getColumnNames();
}
return columnNames.indexOf(encryptLogicColumnName);
}
private void encryptInsertValue(final Encryptor encryptor, final String tableName, final int columnIndex,
final Object originalValue, final StandardParameterBuilder parameterBuilder, final String encryptLogicColumnName) {
// FIXME: can process all part of insert value is ? or literal, can not process mix ? and literal
// For example: values (?, ?), (1, 1) can process
// For example: values (?, 1), (?, 2) can not process
parameterBuilder.addReplacedParameters(columnIndex, encryptor.encrypt(originalValue));
Collection<Object> addedParameters = new LinkedList<>();
if (encryptor instanceof QueryAssistedEncryptor) {
Optional<String> assistedColumnName = getEncryptRule().findAssistedQueryColumn(tableName, encryptLogicColumnName);
Preconditions.checkArgument(assistedColumnName.isPresent(), "Can not find assisted query Column Name");
addedParameters.add(((QueryAssistedEncryptor) encryptor).queryAssistedEncrypt(originalValue.toString()));
}
if (getEncryptRule().findPlainColumn(tableName, encryptLogicColumnName).isPresent()) {
addedParameters.add(originalValue);
}
if (!addedParameters.isEmpty()) {
if (!parameterBuilder.getAddedIndexAndParameters().containsKey(columnIndex + 1)) {
parameterBuilder.getAddedIndexAndParameters().put(columnIndex + 1, new LinkedList<>());
}
parameterBuilder.getAddedIndexAndParameters().get(columnIndex + 1).addAll(addedParameters);
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.parameter.impl;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.rewrite.parameter.EncryptParameterRewriter;
import org.apache.shardingsphere.sql.parser.relation.metadata.RelationMetas;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.encrypt.rewrite.condition.EncryptCondition;
import org.apache.shardingsphere.encrypt.rewrite.condition.EncryptConditionEngine;
import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.ParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.parameter.builder.impl.StandardParameterBuilder;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.aware.RelationMetasAware;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Predicate parameter rewriter for encrypt.
*
* @author zhangliang
*/
@Setter
public final class EncryptPredicateParameterRewriter extends EncryptParameterRewriter implements RelationMetasAware, QueryWithCipherColumnAware {
private RelationMetas relationMetas;
private boolean queryWithCipherColumn;
@Override
protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatementContext) {
return true;
}
@Override
public void rewrite(final ParameterBuilder parameterBuilder, final SQLStatementContext sqlStatementContext, final List<Object> parameters) {
List<EncryptCondition> encryptConditions = new EncryptConditionEngine(getEncryptRule(), relationMetas).createEncryptConditions(sqlStatementContext);
if (encryptConditions.isEmpty()) {
return;
}
for (EncryptCondition each : encryptConditions) {
if (queryWithCipherColumn) {
encryptParameters(parameterBuilder, each.getPositionIndexMap(), getEncryptedValues(each, each.getValues(parameters)));
}
}
}
private List<Object> getEncryptedValues(final EncryptCondition encryptCondition, final List<Object> originalValues) {
String tableName = encryptCondition.getTableName();
String columnName = encryptCondition.getColumnName();
return getEncryptRule().findAssistedQueryColumn(tableName, columnName).isPresent()
? getEncryptRule().getEncryptAssistedQueryValues(tableName, columnName, originalValues) : getEncryptRule().getEncryptValues(tableName, columnName, originalValues);
}
private void encryptParameters(final ParameterBuilder parameterBuilder, final Map<Integer, Integer> positionIndexes, final List<Object> encryptValues) {
if (!positionIndexes.isEmpty()) {
for (Entry<Integer, Integer> entry : positionIndexes.entrySet()) {
((StandardParameterBuilder) parameterBuilder).addReplacedParameters(entry.getValue(), encryptValues.get(entry.getKey()));
}
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.token;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptInsertOnUpdateTokenGenerator;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptForUseDefaultInsertColumnsTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptPredicateColumnTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptPredicateRightValueTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.InsertCipherNameTokenGenerator;
import org.apache.shardingsphere.encrypt.rule.aware.EncryptRuleAware;
import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.AssistQueryAndPlainInsertColumnsTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptAssignmentTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptInsertValuesTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.impl.EncryptProjectionTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.SQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.builder.SQLTokenGeneratorBuilder;
import java.util.Collection;
import java.util.LinkedList;
/**
* SQL token generator builder for encrypt.
*
* @author panjuan
* @author zhangliang
*/
@RequiredArgsConstructor
public final class EncryptTokenGenerateBuilder implements SQLTokenGeneratorBuilder {
private final EncryptRule encryptRule;
private final boolean queryWithCipherColumn;
@Override
public Collection<SQLTokenGenerator> getSQLTokenGenerators() {
Collection<SQLTokenGenerator> result = buildSQLTokenGenerators();
for (SQLTokenGenerator each : result) {
if (each instanceof EncryptRuleAware) {
((EncryptRuleAware) each).setEncryptRule(encryptRule);
}
if (each instanceof QueryWithCipherColumnAware) {
((QueryWithCipherColumnAware) each).setQueryWithCipherColumn(queryWithCipherColumn);
}
}
return result;
}
private Collection<SQLTokenGenerator> buildSQLTokenGenerators() {
Collection<SQLTokenGenerator> result = new LinkedList<>();
result.add(new EncryptProjectionTokenGenerator());
result.add(new EncryptAssignmentTokenGenerator());
result.add(new EncryptPredicateColumnTokenGenerator());
result.add(new EncryptPredicateRightValueTokenGenerator());
result.add(new EncryptInsertValuesTokenGenerator());
result.add(new EncryptForUseDefaultInsertColumnsTokenGenerator());
result.add(new InsertCipherNameTokenGenerator());
result.add(new AssistQueryAndPlainInsertColumnsTokenGenerator());
result.add(new EncryptInsertOnUpdateTokenGenerator());
return result;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.encrypt.rule.aware.EncryptRuleAware;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.SQLTokenGenerator;
/**
* Base SQL token generator for encrypt.
*
* @author zhangliang
*/
@Getter
@Setter
public abstract class BaseEncryptSQLTokenGenerator implements SQLTokenGenerator, EncryptRuleAware {
private EncryptRule encryptRule;
@Override
public final boolean isGenerateSQLToken(final SQLStatementContext sqlStatementContext) {
return isGenerateSQLTokenForEncrypt(sqlStatementContext) && isNeedEncrypt(sqlStatementContext);
}
protected abstract boolean isGenerateSQLTokenForEncrypt(SQLStatementContext sqlStatementContext);
private boolean isNeedEncrypt(final SQLStatementContext sqlStatementContext) {
for (String each : sqlStatementContext.getTablesContext().getTableNames()) {
if (encryptRule.findEncryptTable(each).isPresent()) {
return true;
}
}
return false;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.apache.shardingsphere.encrypt.strategy.EncryptTable;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.InsertColumnsSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.InsertColumnsToken;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* Assist query and plain insert columns token generator.
*
* @author panjuan
* @author zhangliang
*/
public final class AssistQueryAndPlainInsertColumnsTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator {
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext instanceof InsertSQLStatementContext && sqlStatementContext.getSqlStatement().findSQLSegment(InsertColumnsSegment.class).isPresent()
&& !((InsertStatement) sqlStatementContext.getSqlStatement()).useDefaultColumns();
}
@Override
public Collection<InsertColumnsToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
Collection<InsertColumnsToken> result = new LinkedList<>();
Optional<EncryptTable> encryptTable = getEncryptRule().findEncryptTable(sqlStatementContext.getTablesContext().getSingleTableName());
Preconditions.checkState(encryptTable.isPresent());
for (ColumnSegment each : ((InsertStatement) sqlStatementContext.getSqlStatement()).getColumns()) {
List<String> columns = getColumns(encryptTable.get(), each);
if (!columns.isEmpty()) {
result.add(new InsertColumnsToken(each.getStopIndex() + 1, columns));
}
}
return result;
}
private List<String> getColumns(final EncryptTable encryptTable, final ColumnSegment columnSegment) {
List<String> result = new LinkedList<>();
Optional<String> assistedQueryColumn = encryptTable.findAssistedQueryColumn(columnSegment.getName());
if (assistedQueryColumn.isPresent()) {
result.add(assistedQueryColumn.get());
}
Optional<String> plainColumn = encryptTable.findPlainColumn(columnSegment.getName());
if (plainColumn.isPresent()) {
result.add(plainColumn.get());
}
return result;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptAssignmentToken;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptParameterAssignmentToken;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.UpdateStatement;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptLiteralAssignmentToken;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
/**
* Assignment generator for encrypt.
*
* @author panjuan
*/
public final class EncryptAssignmentTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator {
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext.getSqlStatement() instanceof UpdateStatement
|| sqlStatementContext instanceof InsertSQLStatementContext && sqlStatementContext.getSqlStatement().findSQLSegment(SetAssignmentSegment.class).isPresent();
}
@Override
public Collection<EncryptAssignmentToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
Collection<EncryptAssignmentToken> result = new LinkedList<>();
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
for (AssignmentSegment each : getSetAssignmentSegment(sqlStatementContext.getSqlStatement()).getAssignments()) {
if (getEncryptRule().findEncryptor(tableName, each.getColumn().getName()).isPresent()) {
Optional<EncryptAssignmentToken> sqlToken = generateSQLToken(tableName, each);
if (sqlToken.isPresent()) {
result.add(sqlToken.get());
}
}
}
return result;
}
private SetAssignmentSegment getSetAssignmentSegment(final SQLStatement sqlStatement) {
if (sqlStatement instanceof InsertStatement) {
Optional<SetAssignmentSegment> result = ((InsertStatement) sqlStatement).getSetAssignment();
Preconditions.checkState(result.isPresent());
return result.get();
}
return ((UpdateStatement) sqlStatement).getSetAssignment();
}
private Optional<EncryptAssignmentToken> generateSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
if (assignmentSegment.getValue() instanceof ParameterMarkerExpressionSegment) {
return Optional.of(generateParameterSQLToken(tableName, assignmentSegment));
}
if (assignmentSegment.getValue() instanceof LiteralExpressionSegment) {
return Optional.of(generateLiteralSQLToken(tableName, assignmentSegment));
}
return Optional.absent();
}
private EncryptAssignmentToken generateParameterSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
EncryptParameterAssignmentToken result = new EncryptParameterAssignmentToken(assignmentSegment.getColumn().getStartIndex(), assignmentSegment.getStopIndex());
String columnName = assignmentSegment.getColumn().getName();
addCipherColumn(tableName, columnName, result);
addAssistedQueryColumn(tableName, columnName, result);
addPlainColumn(tableName, columnName, result);
return result;
}
private void addCipherColumn(final String tableName, final String columnName, final EncryptParameterAssignmentToken token) {
token.addColumnName(getEncryptRule().getCipherColumn(tableName, columnName));
}
private void addAssistedQueryColumn(final String tableName, final String columnName, final EncryptParameterAssignmentToken token) {
Optional<String> assistedQueryColumn = getEncryptRule().findAssistedQueryColumn(tableName, columnName);
if (assistedQueryColumn.isPresent()) {
token.addColumnName(assistedQueryColumn.get());
}
}
private void addPlainColumn(final String tableName, final String columnName, final EncryptParameterAssignmentToken token) {
Optional<String> plainColumn = getEncryptRule().findPlainColumn(tableName, columnName);
if (plainColumn.isPresent()) {
token.addColumnName(plainColumn.get());
}
}
private EncryptAssignmentToken generateLiteralSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
EncryptLiteralAssignmentToken result = new EncryptLiteralAssignmentToken(assignmentSegment.getColumn().getStartIndex(), assignmentSegment.getStopIndex());
addCipherAssignment(tableName, assignmentSegment, result);
addAssistedQueryAssignment(tableName, assignmentSegment, result);
addPlainAssignment(tableName, assignmentSegment, result);
return result;
}
private void addCipherAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
Object cipherValue = getEncryptRule().getEncryptValues(tableName, assignmentSegment.getColumn().getName(), Collections.singletonList(originalValue)).iterator().next();
token.addAssignment(getEncryptRule().getCipherColumn(tableName, assignmentSegment.getColumn().getName()), cipherValue);
}
private void addAssistedQueryAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
Optional<String> assistedQueryColumn = getEncryptRule().findAssistedQueryColumn(tableName, assignmentSegment.getColumn().getName());
if (assistedQueryColumn.isPresent()) {
Object assistedQueryValue = getEncryptRule().getEncryptAssistedQueryValues(tableName, assignmentSegment.getColumn().getName(), Collections.singletonList(originalValue)).iterator().next();
token.addAssignment(assistedQueryColumn.get(), assistedQueryValue);
}
}
private void addPlainAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
Optional<String> plainColumn = getEncryptRule().findPlainColumn(tableName, assignmentSegment.getColumn().getName());
if (plainColumn.isPresent()) {
token.addAssignment(plainColumn.get(), originalValue);
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.strategy.EncryptTable;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.InsertColumnsSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.OptionalSQLTokenGenerator;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.aware.PreviousSQLTokensAware;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.SQLToken;
import org.apache.shardingsphere.underlying.rewrite.sql.token.pojo.generic.UseDefaultInsertColumnsToken;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* Use default insert columns token generator for encrypt.
*
* @author panjuan
* @author zhangliang
*/
@Setter
public final class EncryptForUseDefaultInsertColumnsTokenGenerator extends BaseEncryptSQLTokenGenerator implements OptionalSQLTokenGenerator, PreviousSQLTokensAware {
private List<SQLToken> previousSQLTokens;
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext instanceof InsertSQLStatementContext && ((InsertStatement) sqlStatementContext.getSqlStatement()).useDefaultColumns();
}
@Override
public UseDefaultInsertColumnsToken generateSQLToken(final SQLStatementContext sqlStatementContext) {
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
Optional<UseDefaultInsertColumnsToken> previousSQLToken = findInsertColumnsToken();
if (previousSQLToken.isPresent()) {
processPreviousSQLToken(previousSQLToken.get(), (InsertSQLStatementContext) sqlStatementContext, tableName);
return previousSQLToken.get();
}
return generateNewSQLToken((InsertSQLStatementContext) sqlStatementContext, tableName);
}
private Optional<UseDefaultInsertColumnsToken> findInsertColumnsToken() {
for (SQLToken each : previousSQLTokens) {
if (each instanceof UseDefaultInsertColumnsToken) {
return Optional.of((UseDefaultInsertColumnsToken) each);
}
}
return Optional.absent();
}
private void processPreviousSQLToken(final UseDefaultInsertColumnsToken previousSQLToken, final InsertSQLStatementContext sqlStatementContext, final String tableName) {
Optional<EncryptTable> encryptTable = getEncryptRule().findEncryptTable(tableName);
Preconditions.checkState(encryptTable.isPresent());
List<String> columnNames = getColumnNames(sqlStatementContext, encryptTable.get(), previousSQLToken.getColumns());
previousSQLToken.getColumns().clear();
previousSQLToken.getColumns().addAll(columnNames);
}
private UseDefaultInsertColumnsToken generateNewSQLToken(final InsertSQLStatementContext sqlStatementContext, final String tableName) {
Optional<InsertColumnsSegment> insertColumnsSegment = sqlStatementContext.getSqlStatement().findSQLSegment(InsertColumnsSegment.class);
Preconditions.checkState(insertColumnsSegment.isPresent());
Optional<EncryptTable> encryptTable = getEncryptRule().findEncryptTable(tableName);
Preconditions.checkState(encryptTable.isPresent());
return new UseDefaultInsertColumnsToken(insertColumnsSegment.get().getStopIndex(), getColumnNames(sqlStatementContext, encryptTable.get(), sqlStatementContext.getColumnNames()));
}
private List<String> getColumnNames(final InsertSQLStatementContext sqlStatementContext, final EncryptTable encryptTable, final List<String> currentColumnNames) {
List<String> result = new LinkedList<>(currentColumnNames);
Iterator<String> descendingColumnNames = sqlStatementContext.getDescendingColumnNames();
while (descendingColumnNames.hasNext()) {
String columnName = descendingColumnNames.next();
if (encryptTable.findEncryptor(columnName).isPresent()) {
int columnIndex = result.indexOf(columnName);
addPlainColumn(result, encryptTable, columnName, columnIndex);
addAssistedQueryColumn(result, encryptTable, columnName, columnIndex);
setCipherColumn(result, encryptTable, columnName, columnIndex);
}
}
return result;
}
private void addPlainColumn(final List<String> columnNames, final EncryptTable encryptTable, final String columnName, final int columnIndex) {
Optional<String> plainColumn = encryptTable.findPlainColumn(columnName);
if (plainColumn.isPresent()) {
columnNames.add(columnIndex + 1, plainColumn.get());
}
}
private void addAssistedQueryColumn(final List<String> columnNames, final EncryptTable encryptTable, final String columnName, final int columnIndex) {
Optional<String> assistedQueryColumn = encryptTable.findAssistedQueryColumn(columnName);
if (assistedQueryColumn.isPresent()) {
columnNames.add(columnIndex + 1, assistedQueryColumn.get());
}
}
private void setCipherColumn(final List<String> columnNames, final EncryptTable encryptTable, final String columnName, final int columnIndex) {
columnNames.set(columnIndex, encryptTable.getCipherColumn(columnName));
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
import com.google.common.base.Optional;
import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptAssignmentToken;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptLiteralAssignmentToken;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptParameterAssignmentToken;
import org.apache.shardingsphere.sql.parser.relation.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.relation.statement.impl.InsertSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.OnDuplicateKeyColumnsSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.underlying.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
/**
* Insert on update values token generator for encrypt.
*
* @author chun.yang
*/
public final class EncryptInsertOnUpdateTokenGenerator extends BaseEncryptSQLTokenGenerator implements CollectionSQLTokenGenerator {
@Override
protected boolean isGenerateSQLTokenForEncrypt(final SQLStatementContext sqlStatementContext) {
return sqlStatementContext instanceof InsertSQLStatementContext && sqlStatementContext.getSqlStatement().findSQLSegment(OnDuplicateKeyColumnsSegment.class).isPresent();
}
@Override
public Collection<EncryptAssignmentToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
Collection<EncryptAssignmentToken> result = new LinkedList<>();
String tableName = sqlStatementContext.getTablesContext().getSingleTableName();
OnDuplicateKeyColumnsSegment onDuplicateKeyColumnsSegment = sqlStatementContext.getSqlStatement().findSQLSegment(OnDuplicateKeyColumnsSegment.class).get();
Collection<AssignmentSegment> onDuplicateKeyColumnsSegments = onDuplicateKeyColumnsSegment.getColumns();
if (onDuplicateKeyColumnsSegments.isEmpty()) {
return result;
}
for (AssignmentSegment each : onDuplicateKeyColumnsSegments) {
if (getEncryptRule().findEncryptor(tableName, each.getColumn().getName()).isPresent()) {
Optional<EncryptAssignmentToken> sqlToken = generateSQLToken(tableName, each);
if (sqlToken.isPresent()) {
result.add(sqlToken.get());
}
}
}
return result;
}
private Optional<EncryptAssignmentToken> generateSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
if (assignmentSegment.getValue() instanceof ParameterMarkerExpressionSegment) {
return Optional.of(generateParameterSQLToken(tableName, assignmentSegment));
}
if (assignmentSegment.getValue() instanceof LiteralExpressionSegment) {
return Optional.of(generateLiteralSQLToken(tableName, assignmentSegment));
}
return Optional.absent();
}
private EncryptAssignmentToken generateParameterSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
EncryptParameterAssignmentToken result = new EncryptParameterAssignmentToken(assignmentSegment.getColumn().getStartIndex(), assignmentSegment.getStopIndex());
String columnName = assignmentSegment.getColumn().getName();
addCipherColumn(tableName, columnName, result);
addPlainColumn(tableName, columnName, result);
return result;
}
private EncryptAssignmentToken generateLiteralSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
EncryptLiteralAssignmentToken result = new EncryptLiteralAssignmentToken(assignmentSegment.getColumn().getStartIndex(), assignmentSegment.getStopIndex());
addCipherAssignment(tableName, assignmentSegment, result);
addPlainAssignment(tableName, assignmentSegment, result);
return result;
}
private void addCipherColumn(final String tableName, final String columnName, final EncryptParameterAssignmentToken token) {
token.addColumnName(getEncryptRule().getCipherColumn(tableName, columnName));
}
private void addPlainColumn(final String tableName, final String columnName, final EncryptParameterAssignmentToken token) {
Optional<String> plainColumn = getEncryptRule().findPlainColumn(tableName, columnName);
if (plainColumn.isPresent()) {
token.addColumnName(plainColumn.get());
}
}
private void addCipherAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
Object cipherValue = getEncryptRule().getEncryptValues(tableName, assignmentSegment.getColumn().getName(), Collections.singletonList(originalValue)).iterator().next();
token.addAssignment(getEncryptRule().getCipherColumn(tableName, assignmentSegment.getColumn().getName()), cipherValue);
}
private void addPlainAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
Optional<String> plainColumn = getEncryptRule().findPlainColumn(tableName, assignmentSegment.getColumn().getName());
if (plainColumn.isPresent()) {
token.addAssignment(plainColumn.get(), originalValue);
}
}
}
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
org.apache.shardingsphere.encrypt.rewrite.fixture.NormalEncryptorFixture
org.apache.shardingsphere.encrypt.rewrite.fixture.QueryAssistedEncryptorFixture
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册