Merge branch 'master' into master
This commit is contained in:
commit
9a74697126
@ -6,3 +6,5 @@
|
|||||||
- [Validating Input With Finite Automata in Java](http://www.baeldung.com/finite-automata-java)
|
- [Validating Input With Finite Automata in Java](http://www.baeldung.com/finite-automata-java)
|
||||||
- [Introduction to Jenetics Library](http://www.baeldung.com/jenetics)
|
- [Introduction to Jenetics Library](http://www.baeldung.com/jenetics)
|
||||||
- [Check If a Number Is Prime in Java](http://www.baeldung.com/java-prime-numbers)
|
- [Check If a Number Is Prime in Java](http://www.baeldung.com/java-prime-numbers)
|
||||||
|
- [Example of Hill Climbing Algorithm](http://www.baeldung.com/java-hill-climbing-algorithm)
|
||||||
|
- [Monte Carlo Tree Search for Tic-Tac-Toe Game](http://www.baeldung.com/java-monte-carlo-tree-search)
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BinarySearch {
|
||||||
|
|
||||||
|
public int runBinarySearchIteratively(int[] sortedArray, int key, int low, int high) {
|
||||||
|
|
||||||
|
int index = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
while (low <= high) {
|
||||||
|
|
||||||
|
int mid = (low + high) / 2;
|
||||||
|
|
||||||
|
if (sortedArray[mid] < key) {
|
||||||
|
low = mid + 1;
|
||||||
|
} else if (sortedArray[mid] > key) {
|
||||||
|
high = mid - 1;
|
||||||
|
} else if (sortedArray[mid] == key) {
|
||||||
|
index = mid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int runBinarySearchRecursively(int[] sortedArray, int key, int low, int high) {
|
||||||
|
|
||||||
|
int middle = (low + high) / 2;
|
||||||
|
if (high < low) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == sortedArray[middle]) {
|
||||||
|
return middle;
|
||||||
|
} else if (key < sortedArray[middle]) {
|
||||||
|
return runBinarySearchRecursively(sortedArray, key, low, middle - 1);
|
||||||
|
} else {
|
||||||
|
return runBinarySearchRecursively(sortedArray, key, middle + 1, high);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int runBinarySearchUsingJavaArrays(int[] sortedArray, Integer key) {
|
||||||
|
int index = Arrays.binarySearch(sortedArray, key);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int runBinarySearchUsingJavaCollections(List<Integer> sortedList, Integer key) {
|
||||||
|
int index = Collections.binarySearch(sortedList, key);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -18,12 +18,12 @@ public class MiniMax {
|
|||||||
constructTree(root);
|
constructTree(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void constructTree(Node node) {
|
private void constructTree(Node parentNode) {
|
||||||
List<Integer> listofPossibleHeaps = GameOfBones.getPossibleStates(node.getNoOfBones());
|
List<Integer> listofPossibleHeaps = GameOfBones.getPossibleStates(parentNode.getNoOfBones());
|
||||||
boolean isMaxPlayer = !node.isMaxPlayer();
|
boolean isChildMaxPlayer = !parentNode.isMaxPlayer();
|
||||||
listofPossibleHeaps.forEach(n -> {
|
listofPossibleHeaps.forEach(n -> {
|
||||||
Node newNode = new Node(n, isMaxPlayer);
|
Node newNode = new Node(n, isChildMaxPlayer);
|
||||||
node.addChild(newNode);
|
parentNode.addChild(newNode);
|
||||||
if (newNode.getNoOfBones() > 0) {
|
if (newNode.getNoOfBones() > 0) {
|
||||||
constructTree(newNode);
|
constructTree(newNode);
|
||||||
}
|
}
|
||||||
|
41
algorithms/src/test/java/algorithms/BinarySearchTest.java
Normal file
41
algorithms/src/test/java/algorithms/BinarySearchTest.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
|
public class BinarySearchTest {
|
||||||
|
|
||||||
|
int[] sortedArray = { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
|
||||||
|
int key = 6;
|
||||||
|
int expectedIndexForSearchKey = 7;
|
||||||
|
int low = 0;
|
||||||
|
int high = sortedArray.length - 1;
|
||||||
|
List<Integer> sortedList = Arrays.asList(0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedArrayOfIntegers_whenBinarySearchRunIterativelyForANumber_thenGetIndexOfTheNumber() {
|
||||||
|
BinarySearch binSearch = new BinarySearch();
|
||||||
|
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchIteratively(sortedArray, key, low, high));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedArrayOfIntegers_whenBinarySearchRunRecursivelyForANumber_thenGetIndexOfTheNumber() {
|
||||||
|
BinarySearch binSearch = new BinarySearch();
|
||||||
|
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchRecursively(sortedArray, key, low, high));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedArrayOfIntegers_whenBinarySearchRunUsingArraysClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
|
||||||
|
BinarySearch binSearch = new BinarySearch();
|
||||||
|
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaArrays(sortedArray, key));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedListOfIntegers_whenBinarySearchRunUsingCollectionsClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
|
||||||
|
BinarySearch binSearch = new BinarySearch();
|
||||||
|
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaCollections(sortedList, key));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
4
apache-shiro/.gitignore
vendored
Normal file
4
apache-shiro/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
/.idea/
|
||||||
|
/target/
|
||||||
|
/apache-shiro.iml
|
0
apache-shiro/README.md
Normal file
0
apache-shiro/README.md
Normal file
78
apache-shiro/pom.xml
Normal file
78
apache-shiro/pom.xml
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>apache-shiro</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.5.2.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<apache-shiro-core-version>1.4.0</apache-shiro-core-version>
|
||||||
|
<log4j-version>1.2.17</log4j-version>
|
||||||
|
<slf4j-version>1.7.25</slf4j-version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.shiro</groupId>
|
||||||
|
<artifactId>shiro-spring-boot-web-starter</artifactId>
|
||||||
|
<version>${apache-shiro-core-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.shiro</groupId>
|
||||||
|
<artifactId>shiro-core</artifactId>
|
||||||
|
<version>${apache-shiro-core-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>jcl-over-slf4j</artifactId>
|
||||||
|
<version>${slf4j-version}</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<version>${slf4j-version}</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>log4j</groupId>
|
||||||
|
<artifactId>log4j</artifactId>
|
||||||
|
<version>${log4j-version}</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.6.2</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
85
apache-shiro/src/main/java/com/baeldung/Main.java
Normal file
85
apache-shiro/src/main/java/com/baeldung/Main.java
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.apache.shiro.authc.*;
|
||||||
|
import org.apache.shiro.mgt.DefaultSecurityManager;
|
||||||
|
import org.apache.shiro.mgt.SecurityManager;
|
||||||
|
import org.apache.shiro.realm.Realm;
|
||||||
|
import org.apache.shiro.realm.text.IniRealm;
|
||||||
|
import org.apache.shiro.session.Session;
|
||||||
|
import org.apache.shiro.subject.Subject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
private static final transient Logger log = LoggerFactory.getLogger(Main.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Realm realm = new MyCustomRealm();
|
||||||
|
SecurityManager securityManager = new DefaultSecurityManager(realm);
|
||||||
|
|
||||||
|
SecurityUtils.setSecurityManager(securityManager);
|
||||||
|
Subject currentUser = SecurityUtils.getSubject();
|
||||||
|
|
||||||
|
if (!currentUser.isAuthenticated()) {
|
||||||
|
UsernamePasswordToken token
|
||||||
|
= new UsernamePasswordToken("user", "password");
|
||||||
|
token.setRememberMe(true);
|
||||||
|
try {
|
||||||
|
currentUser.login(token);
|
||||||
|
} catch (UnknownAccountException uae) {
|
||||||
|
log.error("Username Not Found!", uae);
|
||||||
|
} catch (IncorrectCredentialsException ice) {
|
||||||
|
log.error("Invalid Credentials!", ice);
|
||||||
|
} catch (LockedAccountException lae) {
|
||||||
|
log.error("Your Account is Locked!", lae);
|
||||||
|
} catch (AuthenticationException ae) {
|
||||||
|
log.error("Unexpected Error!", ae);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
|
||||||
|
|
||||||
|
if (currentUser.hasRole("admin")) {
|
||||||
|
log.info("Welcome Admin");
|
||||||
|
} else if(currentUser.hasRole("editor")) {
|
||||||
|
log.info("Welcome, Editor!");
|
||||||
|
} else if(currentUser.hasRole("author")) {
|
||||||
|
log.info("Welcome, Author");
|
||||||
|
} else {
|
||||||
|
log.info("Welcome, Guest");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentUser.isPermitted("articles:compose")) {
|
||||||
|
log.info("You can compose an article");
|
||||||
|
} else {
|
||||||
|
log.info("You are not permitted to compose an article!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentUser.isPermitted("articles:save")) {
|
||||||
|
log.info("You can save articles");
|
||||||
|
} else {
|
||||||
|
log.info("You can not save articles");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentUser.isPermitted("articles:publish")) {
|
||||||
|
log.info("You can publish articles");
|
||||||
|
} else {
|
||||||
|
log.info("You can not publish articles");
|
||||||
|
}
|
||||||
|
|
||||||
|
Session session = currentUser.getSession();
|
||||||
|
session.setAttribute("key", "value");
|
||||||
|
String value = (String) session.getAttribute("key");
|
||||||
|
if (value.equals("value")) {
|
||||||
|
log.info("Retrieved the correct value! [" + value + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
currentUser.logout();
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
102
apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java
Normal file
102
apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.apache.shiro.authc.*;
|
||||||
|
import org.apache.shiro.authz.AuthorizationInfo;
|
||||||
|
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||||
|
import org.apache.shiro.realm.jdbc.JdbcRealm;
|
||||||
|
import org.apache.shiro.subject.PrincipalCollection;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class MyCustomRealm extends JdbcRealm {
|
||||||
|
|
||||||
|
private Map<String, String> credentials = new HashMap<>();
|
||||||
|
private Map<String, Set<String>> roles = new HashMap<>();
|
||||||
|
private Map<String, Set<String>> perm = new HashMap<>();
|
||||||
|
|
||||||
|
{
|
||||||
|
credentials.put("user", "password");
|
||||||
|
credentials.put("user2", "password2");
|
||||||
|
credentials.put("user3", "password3");
|
||||||
|
|
||||||
|
roles.put("user", new HashSet<>(Arrays.asList("admin")));
|
||||||
|
roles.put("user2", new HashSet<>(Arrays.asList("editor")));
|
||||||
|
roles.put("user3", new HashSet<>(Arrays.asList("author")));
|
||||||
|
|
||||||
|
perm.put("admin", new HashSet<>(Arrays.asList("*")));
|
||||||
|
perm.put("editor", new HashSet<>(Arrays.asList("articles:*")));
|
||||||
|
perm.put("author",
|
||||||
|
new HashSet<>(Arrays.asList("articles:compose",
|
||||||
|
"articles:save")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
|
||||||
|
throws AuthenticationException {
|
||||||
|
|
||||||
|
UsernamePasswordToken uToken = (UsernamePasswordToken) token;
|
||||||
|
|
||||||
|
if(uToken.getUsername() == null
|
||||||
|
|| uToken.getUsername().isEmpty()
|
||||||
|
|| !credentials.containsKey(uToken.getUsername())
|
||||||
|
) {
|
||||||
|
throw new UnknownAccountException("username not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new SimpleAuthenticationInfo(
|
||||||
|
uToken.getUsername(), credentials.get(uToken.getUsername()),
|
||||||
|
getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||||
|
Set<String> roleNames = new HashSet<>();
|
||||||
|
Set<String> permissions = new HashSet<>();
|
||||||
|
|
||||||
|
principals.forEach(p -> {
|
||||||
|
try {
|
||||||
|
Set<String> roles = getRoleNamesForUser(null, (String) p);
|
||||||
|
roleNames.addAll(roles);
|
||||||
|
permissions.addAll(getPermissions(null, null,roles));
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
|
||||||
|
info.setStringPermissions(permissions);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Set<String> getRoleNamesForUser(Connection conn, String username) throws SQLException {
|
||||||
|
if(!roles.containsKey(username)) {
|
||||||
|
throw new SQLException("username not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return roles.get(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Set<String> getPermissions(Connection conn, String username, Collection<String> roleNames) throws SQLException {
|
||||||
|
for (String role : roleNames) {
|
||||||
|
if (!perm.containsKey(role)) {
|
||||||
|
throw new SQLException("role not found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> finalSet = new HashSet<>();
|
||||||
|
for (String role : roleNames) {
|
||||||
|
finalSet.addAll(perm.get(role));
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.apache.shiro.realm.Realm;
|
||||||
|
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
|
||||||
|
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by smatt on 21/08/2017.
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class ShiroSpringApplication {
|
||||||
|
|
||||||
|
private static final transient Logger log = LoggerFactory.getLogger(ShiroSpringApplication.class);
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
SpringApplication.run(ShiroSpringApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Realm realm() {
|
||||||
|
return new MyCustomRealm();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
|
||||||
|
DefaultShiroFilterChainDefinition filter
|
||||||
|
= new DefaultShiroFilterChainDefinition();
|
||||||
|
|
||||||
|
filter.addPathDefinition("/secure", "authc");
|
||||||
|
filter.addPathDefinition("/**", "anon");
|
||||||
|
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
package com.baeldung.controllers;
|
||||||
|
|
||||||
|
import com.baeldung.models.UserCredentials;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
|
import org.apache.shiro.subject.Subject;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class ShiroSpringController {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public String index() {
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping( value = "/login", method = {RequestMethod.GET, RequestMethod.POST})
|
||||||
|
public String login(HttpServletRequest req, UserCredentials cred, RedirectAttributes attr) {
|
||||||
|
|
||||||
|
if(req.getMethod().equals(RequestMethod.GET.toString())) {
|
||||||
|
return "login";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
Subject subject = SecurityUtils.getSubject();
|
||||||
|
|
||||||
|
if(!subject.isAuthenticated()) {
|
||||||
|
UsernamePasswordToken token = new UsernamePasswordToken(
|
||||||
|
cred.getUsername(), cred.getPassword(), cred.isRememberMe());
|
||||||
|
try {
|
||||||
|
subject.login(token);
|
||||||
|
} catch (AuthenticationException ae) {
|
||||||
|
ae.printStackTrace();
|
||||||
|
attr.addFlashAttribute("error", "Invalid Credentials");
|
||||||
|
return "redirect:/login";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "redirect:/secure";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/secure")
|
||||||
|
public String secure(ModelMap modelMap) {
|
||||||
|
|
||||||
|
Subject currentUser = SecurityUtils.getSubject();
|
||||||
|
String role = "", permission = "";
|
||||||
|
|
||||||
|
if(currentUser.hasRole("admin")) {
|
||||||
|
role = role + "You are an Admin";
|
||||||
|
}
|
||||||
|
else if(currentUser.hasRole("editor")) {
|
||||||
|
role = role + "You are an Editor";
|
||||||
|
}
|
||||||
|
else if(currentUser.hasRole("author")) {
|
||||||
|
role = role + "You are an Author";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentUser.isPermitted("articles:compose")) {
|
||||||
|
permission = permission + "You can compose an article, ";
|
||||||
|
} else {
|
||||||
|
permission = permission + "You are not permitted to compose an article!, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentUser.isPermitted("articles:save")) {
|
||||||
|
permission = permission + "You can save articles, ";
|
||||||
|
} else {
|
||||||
|
permission = permission + "\nYou can not save articles, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentUser.isPermitted("articles:publish")) {
|
||||||
|
permission = permission + "\nYou can publish articles";
|
||||||
|
} else {
|
||||||
|
permission = permission + "\nYou can not publish articles";
|
||||||
|
}
|
||||||
|
|
||||||
|
modelMap.addAttribute("username", currentUser.getPrincipal());
|
||||||
|
modelMap.addAttribute("permission", permission);
|
||||||
|
modelMap.addAttribute("role", role);
|
||||||
|
|
||||||
|
return "secure";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/logout")
|
||||||
|
public String logout() {
|
||||||
|
Subject subject = SecurityUtils.getSubject();
|
||||||
|
subject.logout();
|
||||||
|
return "redirect:/";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.baeldung.models;
|
||||||
|
|
||||||
|
public class UserCredentials {
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private boolean rememberMe = false;
|
||||||
|
|
||||||
|
public UserCredentials() {}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRememberMe() {
|
||||||
|
return rememberMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRememberMe(boolean rememberMe) {
|
||||||
|
this.rememberMe = rememberMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "username = " + getUsername()
|
||||||
|
+ "\nrememberMe = " + isRememberMe();
|
||||||
|
}
|
||||||
|
}
|
11
apache-shiro/src/main/resources/application.properties
Normal file
11
apache-shiro/src/main/resources/application.properties
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
server.port=9000
|
||||||
|
server.servlet-path=/
|
||||||
|
server.context-path=/
|
||||||
|
|
||||||
|
#shiro-spring-boot-config
|
||||||
|
shiro.loginUrl = /login
|
||||||
|
shiro.successUrl = /secure
|
||||||
|
shiro.unauthorizedUrl = /login
|
||||||
|
|
||||||
|
#freemarker
|
||||||
|
spring.freemarker.suffix=.ftl
|
12
apache-shiro/src/main/resources/log4j.properties
Normal file
12
apache-shiro/src/main/resources/log4j.properties
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
log4j.rootLogger=INFO, stdout
|
||||||
|
|
||||||
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
|
||||||
|
|
||||||
|
log4j.logger.org.apache=WARN
|
||||||
|
|
||||||
|
log4j.logger.org.apache.shiro=INFO
|
||||||
|
|
||||||
|
log4j.logger.org.apache.shiro.util.ThreadContext=WARN
|
||||||
|
log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
|
9
apache-shiro/src/main/resources/shiro.ini
Normal file
9
apache-shiro/src/main/resources/shiro.ini
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[users]
|
||||||
|
user = password,admin
|
||||||
|
user2 = password2,editor
|
||||||
|
user3 = password3,author
|
||||||
|
|
||||||
|
[roles]
|
||||||
|
admin = *
|
||||||
|
editor = articles:*
|
||||||
|
author = articles:compose,articles:save
|
10
apache-shiro/src/main/resources/templates/index.ftl
Normal file
10
apache-shiro/src/main/resources/templates/index.ftl
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Index</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Welcome Guest!</h1>
|
||||||
|
<br>
|
||||||
|
<a href="/login">Login</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
27
apache-shiro/src/main/resources/templates/login.ftl
Normal file
27
apache-shiro/src/main/resources/templates/login.ftl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Login</title>
|
||||||
|
</head>
|
||||||
|
<body style="margin-left: 30px;">
|
||||||
|
<h3>Login</h3>
|
||||||
|
<br>
|
||||||
|
<form action="/login" method="post">
|
||||||
|
<#if (error?length > 0)??>
|
||||||
|
<p style="color:darkred;">${error}</p>
|
||||||
|
<#else>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<br>
|
||||||
|
<input type="text" name="username">
|
||||||
|
<br><br>
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<br>
|
||||||
|
<input type="password" name="password">
|
||||||
|
<br><br>
|
||||||
|
<input type="checkbox" name="rememberMe"> Remember Me
|
||||||
|
<br><br>
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
apache-shiro/src/main/resources/templates/secure.ftl
Normal file
15
apache-shiro/src/main/resources/templates/secure.ftl
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Secure</title>
|
||||||
|
</head>
|
||||||
|
<body style="margin-left: 30px;">
|
||||||
|
<h1>Welcome ${username}!</h1>
|
||||||
|
<p><strong>Role</strong>: ${role}</p>
|
||||||
|
<p><strong>Permissions</strong></p>
|
||||||
|
<p>${permission}</p>
|
||||||
|
<br>
|
||||||
|
<form role="form" action="/logout" method="POST">
|
||||||
|
<input type="Submit" value="Logout" />
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,4 +1,4 @@
|
|||||||
resource.loader=webapp
|
resource.loader=webapp
|
||||||
webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
|
webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
|
||||||
webapp.resource.loader.path = .
|
webapp.resource.loader.path =
|
||||||
webapp.resource.loader.cache = true
|
webapp.resource.loader.cache = true
|
@ -1,3 +1,4 @@
|
|||||||
### Relevant articles
|
### Relevant articles
|
||||||
|
|
||||||
- [Introduction to Asciidoctor](http://www.baeldung.com/introduction-to-asciidoctor)
|
- [Introduction to Asciidoctor](http://www.baeldung.com/introduction-to-asciidoctor)
|
||||||
|
- [Generating a Book with Asciidoctor](http://www.baeldung.com/asciidoctor-book)
|
||||||
|
@ -35,7 +35,12 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<sourceDirectory>src/docs/asciidoc</sourceDirectory>
|
<sourceDirectory>src/docs/asciidoc</sourceDirectory>
|
||||||
<outputDirectory>target/docs/asciidoc</outputDirectory>
|
<outputDirectory>target/docs/asciidoc</outputDirectory>
|
||||||
|
<attributes>
|
||||||
|
<pdf-stylesdir>${project.basedir}/src/themes</pdf-stylesdir>
|
||||||
|
<pdf-style>custom</pdf-style>
|
||||||
|
</attributes>
|
||||||
<backend>pdf</backend>
|
<backend>pdf</backend>
|
||||||
|
<doctype>book</doctype>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
== Introduction Section
|
:icons: font
|
||||||
|
|
||||||
Hi. I'm a simple test to see if this Maven build is working. If you see me in a nice PDF, then it means everything is [red]#working#.
|
|
||||||
|
= Generating book with AsciiDoctorj
|
||||||
|
Baeldung
|
||||||
|
|
||||||
|
[abstract]
|
||||||
|
This is the actual content.
|
||||||
|
|
||||||
|
== First Section
|
||||||
|
|
||||||
|
This is first section of the book where you can include some nice icons like icon:comment[].
|
||||||
|
You can also create http://www.baeldung.com[links]
|
||||||
|
29
asciidoctor/src/themes/custom-theme.yml
Normal file
29
asciidoctor/src/themes/custom-theme.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
title_page:
|
||||||
|
align: left
|
||||||
|
|
||||||
|
page:
|
||||||
|
layout: portrait
|
||||||
|
margin: [0.75in, 1in, 0.75in, 1in]
|
||||||
|
size: A4
|
||||||
|
base:
|
||||||
|
font_color: #333333
|
||||||
|
line_height_length: 17
|
||||||
|
line_height: $base_line_height_length / $base_font_size
|
||||||
|
link:
|
||||||
|
font_color: #009900
|
||||||
|
|
||||||
|
header:
|
||||||
|
height: 0.5in
|
||||||
|
line_height: 1
|
||||||
|
recto_content:
|
||||||
|
center: '{document-title}'
|
||||||
|
verso_content:
|
||||||
|
center: '{document-title}'
|
||||||
|
|
||||||
|
footer:
|
||||||
|
height: 0.5in
|
||||||
|
line_height: 1
|
||||||
|
recto_content:
|
||||||
|
right: '{chapter-title} | *{page-number}*'
|
||||||
|
verso_content:
|
||||||
|
left: '*{page-number}* | {chapter-title}'
|
32
aws/pom.xml
32
aws/pom.xml
@ -18,9 +18,41 @@
|
|||||||
<aws-lambda-java-events.version>1.3.0</aws-lambda-java-events.version>
|
<aws-lambda-java-events.version>1.3.0</aws-lambda-java-events.version>
|
||||||
<aws-lambda-java-core.version>1.1.0</aws-lambda-java-core.version>
|
<aws-lambda-java-core.version>1.1.0</aws-lambda-java-core.version>
|
||||||
<gson.version>2.8.0</gson.version>
|
<gson.version>2.8.0</gson.version>
|
||||||
|
<aws-java-sdk.version>1.11.154</aws-java-sdk.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
<mockito-core.version>2.8.9</mockito-core.version>
|
||||||
|
<assertj-core.version>3.8.0</assertj-core.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.amazonaws</groupId>
|
||||||
|
<artifactId>aws-java-sdk</artifactId>
|
||||||
|
<version>${aws-java-sdk.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<version>${mockito-core.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj-core.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.amazonaws</groupId>
|
<groupId>com.amazonaws</groupId>
|
||||||
<artifactId>aws-lambda-java-core</artifactId>
|
<artifactId>aws-lambda-java-core</artifactId>
|
||||||
|
87
aws/src/main/java/com/baeldung/s3/AWSS3Service.java
Normal file
87
aws/src/main/java/com/baeldung/s3/AWSS3Service.java
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package com.baeldung.s3;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.amazonaws.services.s3.AmazonS3;
|
||||||
|
import com.amazonaws.services.s3.AmazonS3Client;
|
||||||
|
import com.amazonaws.services.s3.model.Bucket;
|
||||||
|
import com.amazonaws.services.s3.model.CopyObjectResult;
|
||||||
|
import com.amazonaws.services.s3.model.DeleteObjectsRequest;
|
||||||
|
import com.amazonaws.services.s3.model.DeleteObjectsResult;
|
||||||
|
import com.amazonaws.services.s3.model.ObjectListing;
|
||||||
|
import com.amazonaws.services.s3.model.PutObjectResult;
|
||||||
|
import com.amazonaws.services.s3.model.S3Object;
|
||||||
|
|
||||||
|
public class AWSS3Service {
|
||||||
|
private final AmazonS3 s3client;
|
||||||
|
|
||||||
|
public AWSS3Service() {
|
||||||
|
this(new AmazonS3Client() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public AWSS3Service(AmazonS3 s3client) {
|
||||||
|
this.s3client = s3client;
|
||||||
|
}
|
||||||
|
|
||||||
|
//is bucket exist?
|
||||||
|
public boolean doesBucketExist(String bucketName) {
|
||||||
|
return s3client.doesBucketExist(bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//create a bucket
|
||||||
|
public Bucket createBucket(String bucketName) {
|
||||||
|
return s3client.createBucket(bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//list all buckets
|
||||||
|
public List<Bucket> listBuckets() {
|
||||||
|
return s3client.listBuckets();
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete a bucket
|
||||||
|
public void deleteBucket(String bucketName) {
|
||||||
|
s3client.deleteBucket(bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//uploading object
|
||||||
|
public PutObjectResult putObject(String bucketName, String key, File file) {
|
||||||
|
return s3client.putObject(bucketName, key, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
//listing objects
|
||||||
|
public ObjectListing listObjects(String bucketName) {
|
||||||
|
return s3client.listObjects(bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//get an object
|
||||||
|
public S3Object getObject(String bucketName, String objectKey) {
|
||||||
|
return s3client.getObject(bucketName, objectKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
//copying an object
|
||||||
|
public CopyObjectResult copyObject(
|
||||||
|
String sourceBucketName,
|
||||||
|
String sourceKey,
|
||||||
|
String destinationBucketName,
|
||||||
|
String destinationKey
|
||||||
|
) {
|
||||||
|
return s3client.copyObject(
|
||||||
|
sourceBucketName,
|
||||||
|
sourceKey,
|
||||||
|
destinationBucketName,
|
||||||
|
destinationKey
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//deleting an object
|
||||||
|
public void deleteObject(String bucketName, String objectKey) {
|
||||||
|
s3client.deleteObject(bucketName, objectKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
//deleting multiple Objects
|
||||||
|
public DeleteObjectsResult deleteObjects(DeleteObjectsRequest delObjReq) {
|
||||||
|
return s3client.deleteObjects(delObjReq);
|
||||||
|
}
|
||||||
|
}
|
101
aws/src/main/java/com/baeldung/s3/S3Application.java
Normal file
101
aws/src/main/java/com/baeldung/s3/S3Application.java
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package com.baeldung.s3;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
|
import com.amazonaws.auth.AWSCredentials;
|
||||||
|
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||||
|
import com.amazonaws.auth.BasicAWSCredentials;
|
||||||
|
import com.amazonaws.regions.Regions;
|
||||||
|
import com.amazonaws.services.s3.AmazonS3;
|
||||||
|
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||||
|
import com.amazonaws.services.s3.model.Bucket;
|
||||||
|
import com.amazonaws.services.s3.model.DeleteObjectsRequest;
|
||||||
|
import com.amazonaws.services.s3.model.ObjectListing;
|
||||||
|
import com.amazonaws.services.s3.model.S3Object;
|
||||||
|
import com.amazonaws.services.s3.model.S3ObjectInputStream;
|
||||||
|
import com.amazonaws.services.s3.model.S3ObjectSummary;
|
||||||
|
|
||||||
|
public class S3Application {
|
||||||
|
|
||||||
|
private static final AWSCredentials credentials;
|
||||||
|
private static String bucketName;
|
||||||
|
|
||||||
|
static {
|
||||||
|
//put your accesskey and secretkey here
|
||||||
|
credentials = new BasicAWSCredentials(
|
||||||
|
"<AWS accesskey>",
|
||||||
|
"<AWS secretkey>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
//set-up the client
|
||||||
|
AmazonS3 s3client = AmazonS3ClientBuilder
|
||||||
|
.standard()
|
||||||
|
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||||
|
.withRegion(Regions.US_EAST_2)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
AWSS3Service awsService = new AWSS3Service(s3client);
|
||||||
|
|
||||||
|
bucketName = "baeldung-bucket";
|
||||||
|
|
||||||
|
//creating a bucket
|
||||||
|
if(awsService.doesBucketExist(bucketName)) {
|
||||||
|
System.out.println("Bucket name is not available."
|
||||||
|
+ " Try again with a different Bucket name.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
awsService.createBucket(bucketName);
|
||||||
|
|
||||||
|
//list all the buckets
|
||||||
|
for(Bucket s : awsService.listBuckets() ) {
|
||||||
|
System.out.println(s.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
//deleting bucket
|
||||||
|
awsService.deleteBucket("baeldung-bucket-test2");
|
||||||
|
|
||||||
|
//uploading object
|
||||||
|
awsService.putObject(
|
||||||
|
bucketName,
|
||||||
|
"Document/hello.txt",
|
||||||
|
new File("/Users/user/Document/hello.txt")
|
||||||
|
);
|
||||||
|
|
||||||
|
//listing objects
|
||||||
|
ObjectListing objectListing = awsService.listObjects(bucketName);
|
||||||
|
for(S3ObjectSummary os : objectListing.getObjectSummaries()) {
|
||||||
|
System.out.println(os.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
//downloading an object
|
||||||
|
S3Object s3object = awsService.getObject(bucketName, "Document/hello.txt");
|
||||||
|
S3ObjectInputStream inputStream = s3object.getObjectContent();
|
||||||
|
FileUtils.copyInputStreamToFile(inputStream, new File("/Users/user/Desktop/hello.txt"));
|
||||||
|
|
||||||
|
//copying an object
|
||||||
|
awsService.copyObject(
|
||||||
|
"baeldung-bucket",
|
||||||
|
"picture/pic.png",
|
||||||
|
"baeldung-bucket2",
|
||||||
|
"Document/picture.png"
|
||||||
|
);
|
||||||
|
|
||||||
|
//deleting an object
|
||||||
|
awsService.deleteObject(bucketName, "Document/hello.txt");
|
||||||
|
|
||||||
|
//deleting multiple objects
|
||||||
|
String objkeyArr[] = {
|
||||||
|
"Document/hello2.txt",
|
||||||
|
"Document/picture.png"
|
||||||
|
};
|
||||||
|
|
||||||
|
DeleteObjectsRequest delObjReq = new DeleteObjectsRequest("baeldung-bucket")
|
||||||
|
.withKeys(objkeyArr);
|
||||||
|
awsService.deleteObjects(delObjReq);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
package com.baeldung.s3;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.amazonaws.services.s3.AmazonS3;
|
||||||
|
import com.amazonaws.services.s3.model.CopyObjectResult;
|
||||||
|
import com.amazonaws.services.s3.model.DeleteObjectsRequest;
|
||||||
|
import com.amazonaws.services.s3.model.DeleteObjectsResult;
|
||||||
|
import com.amazonaws.services.s3.model.PutObjectResult;
|
||||||
|
|
||||||
|
public class AWSS3ServiceIntegrationTest {
|
||||||
|
|
||||||
|
private static final String BUCKET_NAME = "bucket_name";
|
||||||
|
private static final String KEY_NAME = "key_name";
|
||||||
|
private static final String BUCKET_NAME2 = "bucket_name2";
|
||||||
|
private static final String KEY_NAME2 = "key_name2";
|
||||||
|
|
||||||
|
private AmazonS3 s3;
|
||||||
|
private AWSS3Service service;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
s3 = mock(AmazonS3.class);
|
||||||
|
service = new AWSS3Service(s3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInitializingAWSS3Service_thenNotNull() {
|
||||||
|
assertThat(new AWSS3Service()).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenVerifyingIfS3BucketExist_thenCorrect() {
|
||||||
|
service.doesBucketExist(BUCKET_NAME);
|
||||||
|
verify(s3).doesBucketExist(BUCKET_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenVerifyingCreationOfS3Bucket_thenCorrect() {
|
||||||
|
service.createBucket(BUCKET_NAME);
|
||||||
|
verify(s3).createBucket(BUCKET_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenVerifyingListBuckets_thenCorrect() {
|
||||||
|
service.listBuckets();
|
||||||
|
verify(s3).listBuckets();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDeletingBucket_thenCorrect() {
|
||||||
|
service.deleteBucket(BUCKET_NAME);
|
||||||
|
verify(s3).deleteBucket(BUCKET_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenVerifyingPutObject_thenCorrect() {
|
||||||
|
File file = mock(File.class);
|
||||||
|
PutObjectResult result = mock(PutObjectResult.class);
|
||||||
|
when(s3.putObject(anyString(), anyString(), (File) any())).thenReturn(result);
|
||||||
|
|
||||||
|
assertThat(service.putObject(BUCKET_NAME, KEY_NAME, file)).isEqualTo(result);
|
||||||
|
verify(s3).putObject(BUCKET_NAME, KEY_NAME, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenVerifyingListObjects_thenCorrect() {
|
||||||
|
service.listObjects(BUCKET_NAME);
|
||||||
|
verify(s3).listObjects(BUCKET_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenVerifyingGetObject_thenCorrect() {
|
||||||
|
service.getObject(BUCKET_NAME, KEY_NAME);
|
||||||
|
verify(s3).getObject(BUCKET_NAME, KEY_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenVerifyingCopyObject_thenCorrect() {
|
||||||
|
CopyObjectResult result = mock(CopyObjectResult.class);
|
||||||
|
when(s3.copyObject(anyString(), anyString(), anyString(), anyString())).thenReturn(result);
|
||||||
|
|
||||||
|
assertThat(service.copyObject(BUCKET_NAME, KEY_NAME, BUCKET_NAME2, KEY_NAME2)).isEqualTo(result);
|
||||||
|
verify(s3).copyObject(BUCKET_NAME, KEY_NAME, BUCKET_NAME2, KEY_NAME2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenVerifyingDeleteObject_thenCorrect() {
|
||||||
|
service.deleteObject(BUCKET_NAME, KEY_NAME);
|
||||||
|
verify(s3).deleteObject(BUCKET_NAME, KEY_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenVerifyingDeleteObjects_thenCorrect() {
|
||||||
|
DeleteObjectsRequest request = mock(DeleteObjectsRequest.class);
|
||||||
|
DeleteObjectsResult result = mock(DeleteObjectsResult.class);
|
||||||
|
when(s3.deleteObjects((DeleteObjectsRequest)any())).thenReturn(result);
|
||||||
|
|
||||||
|
assertThat(service.deleteObjects(request)).isEqualTo(result);
|
||||||
|
verify(s3).deleteObjects(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
bootique/config.yml
Normal file
11
bootique/config.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
log:
|
||||||
|
level: warn
|
||||||
|
appenders:
|
||||||
|
- type: file
|
||||||
|
logFormat: '%c{20}: %m%n'
|
||||||
|
file: /home/logger.log
|
||||||
|
|
||||||
|
jetty:
|
||||||
|
context: /hello
|
||||||
|
connector:
|
||||||
|
port: 10001
|
50
bootique/dependency-reduced-pom.xml
Normal file
50
bootique/dependency-reduced-pom.xml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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/maven-v4_0_0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>bootique-parent</artifactId>
|
||||||
|
<groupId>io.bootique.parent</groupId>
|
||||||
|
<version>0.12</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung.bootique</groupId>
|
||||||
|
<artifactId>bootique</artifactId>
|
||||||
|
<name>bootique</name>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.bootique</groupId>
|
||||||
|
<artifactId>bootique-test</artifactId>
|
||||||
|
<version>0.23</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.bootique.bom</groupId>
|
||||||
|
<artifactId>bootique-bom</artifactId>
|
||||||
|
<version>0.23</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
<properties>
|
||||||
|
<main.class>com.baeldung.bootique.App</main.class>
|
||||||
|
</properties>
|
||||||
|
</project>
|
||||||
|
|
66
bootique/pom.xml
Normal file
66
bootique/pom.xml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<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/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung.bootique</groupId>
|
||||||
|
<artifactId>bootique</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>bootique</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<main.class>com.baeldung.bootique.App</main.class>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>io.bootique.parent</groupId>
|
||||||
|
<artifactId>bootique-parent</artifactId>
|
||||||
|
<version>0.12</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.bootique.bom</groupId>
|
||||||
|
<artifactId>bootique-bom</artifactId>
|
||||||
|
<version>0.23</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.bootique.jersey</groupId>
|
||||||
|
<artifactId>bootique-jersey</artifactId>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.bootique.logback</groupId>
|
||||||
|
<artifactId>bootique-logback</artifactId>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.bootique</groupId>
|
||||||
|
<artifactId>bootique-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
41
bootique/src/main/java/com/baeldung/bootique/App.java
Normal file
41
bootique/src/main/java/com/baeldung/bootique/App.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package com.baeldung.bootique;
|
||||||
|
|
||||||
|
import com.baeldung.bootique.module.ModuleBinder;
|
||||||
|
import com.baeldung.bootique.router.IndexController;
|
||||||
|
import com.baeldung.bootique.router.SaveController;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
import io.bootique.Bootique;
|
||||||
|
import io.bootique.jersey.JerseyModule;
|
||||||
|
import io.bootique.log.BootLogger;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Module module = binder -> JerseyModule.extend(binder).addResource(IndexController.class)
|
||||||
|
.addResource(SaveController.class);
|
||||||
|
Bootique.app(args).module(module).module(ModuleBinder.class).bootLogger(new BootLogger() {
|
||||||
|
@Override
|
||||||
|
public void trace(Supplier<String> arg0) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stdout(String arg0) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stderr(String arg0, Throwable arg1) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stderr(String arg0) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}).autoLoadModules().exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.baeldung.bootique.module;
|
||||||
|
|
||||||
|
import com.baeldung.bootique.service.HelloService;
|
||||||
|
import com.baeldung.bootique.service.impl.HelloServiceImpl;
|
||||||
|
import com.google.inject.Binder;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
public class ModuleBinder implements Module {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(Binder binder) {
|
||||||
|
binder.bind(HelloService.class).to(HelloServiceImpl.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.bootique.module;
|
||||||
|
|
||||||
|
import com.google.inject.Module;
|
||||||
|
import io.bootique.BQModuleProvider;
|
||||||
|
|
||||||
|
public class ModuleProvider implements BQModuleProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Module module() {
|
||||||
|
return new ModuleBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.baeldung.bootique.router;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
|
||||||
|
@Path("/")
|
||||||
|
public class IndexController {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
public String index() {
|
||||||
|
return "Hello, baeldung!";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.bootique.router;
|
||||||
|
|
||||||
|
import com.baeldung.bootique.service.HelloService;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
|
||||||
|
@Path("/save")
|
||||||
|
public class SaveController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
HelloService helloService;
|
||||||
|
|
||||||
|
@POST
|
||||||
|
public String save() {
|
||||||
|
return "Data Saved!";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.baeldung.bootique.service;
|
||||||
|
|
||||||
|
public interface HelloService {
|
||||||
|
|
||||||
|
boolean save();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.bootique.service.impl;
|
||||||
|
|
||||||
|
import com.baeldung.bootique.service.HelloService;
|
||||||
|
|
||||||
|
public class HelloServiceImpl implements HelloService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean save() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
com.baeldung.bootique.module.ModuleProvider
|
27
bootique/src/test/java/com/baeldung/bootique/AppTest.java
Normal file
27
bootique/src/test/java/com/baeldung/bootique/AppTest.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package com.baeldung.bootique;
|
||||||
|
|
||||||
|
import com.baeldung.bootique.service.HelloService;
|
||||||
|
import io.bootique.BQRuntime;
|
||||||
|
import io.bootique.test.junit.BQDaemonTestFactory;
|
||||||
|
import io.bootique.test.junit.BQTestFactory;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class AppTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public BQTestFactory bqTestFactory = new BQTestFactory();
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public BQDaemonTestFactory bqDaemonTestFactory = new BQDaemonTestFactory();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenService_expectBoolen() {
|
||||||
|
BQRuntime runtime = bqTestFactory.app("--server").autoLoadModules().createRuntime();
|
||||||
|
HelloService service = runtime.getInstance(HelloService.class);
|
||||||
|
assertEquals(true, service.save());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,14 +13,13 @@ import org.springframework.beans.factory.annotation.Value;
|
|||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@ComponentScan(basePackages="com.baeldung.camel")
|
@ComponentScan(basePackages="com.baeldung.camel")
|
||||||
public class Application extends SpringBootServletInitializer {
|
public class Application{
|
||||||
|
|
||||||
@Value("${server.port}")
|
@Value("${server.port}")
|
||||||
String serverPort;
|
String serverPort;
|
||||||
@ -62,10 +61,12 @@ public class Application extends SpringBootServletInitializer {
|
|||||||
.bindingMode(RestBindingMode.json)
|
.bindingMode(RestBindingMode.json)
|
||||||
.dataFormatProperty("prettyPrint", "true");
|
.dataFormatProperty("prettyPrint", "true");
|
||||||
/**
|
/**
|
||||||
The Rest DSL supports automatic binding json/xml contents to/from POJOs using Camels Data Format.
|
The Rest DSL supports automatic binding json/xml contents to/from
|
||||||
By default the binding mode is off, meaning there is no automatic binding happening for incoming and outgoing messages.
|
POJOs using Camels Data Format.
|
||||||
You may want to use binding if you develop POJOs that maps to your REST services request and response types.
|
By default the binding mode is off, meaning there is no automatic
|
||||||
This allows you, as a developer, to work with the POJOs in Java code.
|
binding happening for incoming and outgoing messages.
|
||||||
|
You may want to use binding if you develop POJOs that maps to
|
||||||
|
your REST services request and response types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rest("/api/").description("Teste REST Service")
|
rest("/api/").description("Teste REST Service")
|
||||||
|
@ -13,3 +13,6 @@
|
|||||||
- [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api)
|
- [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api)
|
||||||
- [Introduction to Java 9 StackWalking API](http://www.baeldung.com/java-9-stackwalking-api)
|
- [Introduction to Java 9 StackWalking API](http://www.baeldung.com/java-9-stackwalking-api)
|
||||||
- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity)
|
- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity)
|
||||||
|
- [Java 9 Optional API Additions](http://www.baeldung.com/java-9-optional)
|
||||||
|
- [Java 9 Reactive Streams](http://www.baeldung.com/java-9-reactive-streams)
|
||||||
|
- [How to Get All Dates Between Two Dates?](http://www.baeldung.com/java-between-dates)
|
||||||
|
@ -6,7 +6,7 @@ public class ServiceMain {
|
|||||||
|
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
ProcessHandle thisProcess = ProcessHandle.current();
|
ProcessHandle thisProcess = ProcessHandle.current();
|
||||||
long pid = thisProcess.getPid();
|
long pid = thisProcess.pid();
|
||||||
|
|
||||||
Optional<String[]> opArgs = Optional.ofNullable(args);
|
Optional<String[]> opArgs = Optional.ofNullable(args);
|
||||||
String procName = opArgs.map(str -> str.length > 0 ? str[0] : null).orElse(System.getProperty("sun.java.command"));
|
String procName = opArgs.map(str -> str.length > 0 ? str[0] : null).orElse(System.getProperty("sun.java.command"));
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.baeldung.java9.language;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
public class Java9ObjectsAPIUnitTest {
|
||||||
|
|
||||||
|
private List<String> aMethodReturningNullList(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNullObject_whenRequireNonNullElse_thenElse(){
|
||||||
|
List<String> aList = Objects.<List>requireNonNullElse(
|
||||||
|
aMethodReturningNullList(), Collections.EMPTY_LIST);
|
||||||
|
assertThat(aList, is(Collections.EMPTY_LIST));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> aMethodReturningNonNullList(){
|
||||||
|
return List.of("item1", "item2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenObject_whenRequireNonNullElse_thenObject(){
|
||||||
|
List<String> aList = Objects.<List>requireNonNullElse(
|
||||||
|
aMethodReturningNonNullList(), Collections.EMPTY_LIST);
|
||||||
|
assertThat(aList, is(List.of("item1", "item2")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void givenNull_whenRequireNonNullElse_thenException(){
|
||||||
|
Objects.<List>requireNonNullElse(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenObject_whenRequireNonNullElseGet_thenObject(){
|
||||||
|
List<String> aList = Objects.<List>requireNonNullElseGet(null, List::of);
|
||||||
|
assertThat(aList, is(List.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNumber_whenInvokeCheckIndex_thenNumber(){
|
||||||
|
int length = 5;
|
||||||
|
assertThat(Objects.checkIndex(4, length), is(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
|
public void givenOutOfRangeNumber_whenInvokeCheckIndex_thenException(){
|
||||||
|
int length = 5;
|
||||||
|
Objects.checkIndex(5, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSubRange_whenCheckFromToIndex_thenNumber(){
|
||||||
|
int length = 6;
|
||||||
|
assertThat(Objects.checkFromToIndex(2,length,length), is(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
|
public void givenInvalidSubRange_whenCheckFromToIndex_thenException(){
|
||||||
|
int length = 6;
|
||||||
|
Objects.checkFromToIndex(2,7,length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSubRange_whenCheckFromIndexSize_thenNumber(){
|
||||||
|
int length = 6;
|
||||||
|
assertThat(Objects.checkFromIndexSize(2,3,length), is(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
|
public void givenInvalidSubRange_whenCheckFromIndexSize_thenException(){
|
||||||
|
int length = 6;
|
||||||
|
Objects.checkFromIndexSize(2, 6, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
26
core-java-concurrency/.gitignore
vendored
Normal file
26
core-java-concurrency/.gitignore
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
*.class
|
||||||
|
|
||||||
|
0.*
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
.resourceCache
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
|
||||||
|
# Files generated by integration tests
|
||||||
|
*.txt
|
||||||
|
backup-pom.xml
|
||||||
|
/bin/
|
||||||
|
/temp
|
||||||
|
|
||||||
|
#IntelliJ specific
|
||||||
|
.idea/
|
||||||
|
*.iml
|
32
core-java-concurrency/README.md
Normal file
32
core-java-concurrency/README.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
=========
|
||||||
|
|
||||||
|
## Core Java Concurrency Examples
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Guide To CompletableFuture](http://www.baeldung.com/java-completablefuture)
|
||||||
|
- [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial)
|
||||||
|
- [Introduction to Thread Pools in Java](http://www.baeldung.com/thread-pool-java-and-guava)
|
||||||
|
- [Guide to java.util.concurrent.Future](http://www.baeldung.com/java-future)
|
||||||
|
- [Guide to java.util.concurrent.BlockingQueue](http://www.baeldung.com/java-blocking-queue)
|
||||||
|
- [Guide to CountDownLatch in Java](http://www.baeldung.com/java-countdown-latch)
|
||||||
|
- [A Guide to ConcurrentMap](http://www.baeldung.com/java-concurrent-map)
|
||||||
|
- [Guide to PriorityBlockingQueue in Java](http://www.baeldung.com/java-priority-blocking-queue)
|
||||||
|
- [Avoiding the ConcurrentModificationException in Java](http://www.baeldung.com/java-concurrentmodificationexception)
|
||||||
|
- [Custom Thread Pools In Java 8 Parallel Streams](http://www.baeldung.com/java-8-parallel-streams-custom-threadpool)
|
||||||
|
- [Guide to java.util.concurrent.Locks](http://www.baeldung.com/java-concurrent-locks)
|
||||||
|
- [An Introduction to ThreadLocal in Java](http://www.baeldung.com/java-threadlocal)
|
||||||
|
- [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue)
|
||||||
|
- [A Guide to Java SynchronousQueue](http://www.baeldung.com/java-synchronous-queue)
|
||||||
|
- [Guide to the Java TransferQueue](http://www.baeldung.com/java-transfer-queue)
|
||||||
|
- [Guide to the ConcurrentSkipListMap](http://www.baeldung.com/java-concurrent-skip-list-map)
|
||||||
|
- [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep)
|
||||||
|
- [LongAdder and LongAccumulator in Java](http://www.baeldung.com/java-longadder-and-longaccumulator)
|
||||||
|
- [The Dining Philosophers Problem in Java](http://www.baeldung.com/java-dining-philoshophers)
|
||||||
|
- [Guide to CopyOnWriteArrayList](http://www.baeldung.com/java-copy-on-write-arraylist)
|
||||||
|
- [Guide to the Java Phaser](http://www.baeldung.com/java-phaser)
|
||||||
|
- [Guide to Synchronized Keyword in Java](http://www.baeldung.com/java-synchronized)
|
||||||
|
- [An Introduction to Atomic Variables in Java](http://www.baeldung.com/java-atomic-variables)
|
||||||
|
- [CyclicBarrier in Java](http://www.baeldung.com/java-cyclic-barrier)
|
||||||
|
- [Guide to Volatile Keyword in Java](http://www.baeldung.com/java-volatile)
|
||||||
|
- [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent)
|
||||||
|
- [Semaphores in Java](http://www.baeldung.com/java-semaphore)
|
237
core-java-concurrency/pom.xml
Normal file
237
core-java-concurrency/pom.xml
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
<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>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>core-java-concurrency</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>core-java-concurrency</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- utils -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
<version>${commons-collections4.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>${commons-io.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-math3</artifactId>
|
||||||
|
<version>${commons-math3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- test scoped -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jayway.awaitility</groupId>
|
||||||
|
<artifactId>awaitility</artifactId>
|
||||||
|
<version>${avaitility.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>core-java-concurrency</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-dependencies</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<classpathPrefix>libs/</classpathPrefix>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<archiveBaseDirectory>${project.basedir}</archiveBaseDirectory>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||||
|
<transformers>
|
||||||
|
<transformer
|
||||||
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.jolira</groupId>
|
||||||
|
<artifactId>onejar-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
<attachToBuild>true</attachToBuild>
|
||||||
|
<filename>${project.build.finalName}-onejar.${project.packaging}</filename>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>one-jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<classifier>spring-boot</classifier>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>integration</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*ManualTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
<includes>
|
||||||
|
<include>**/*IntegrationTest.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<test.mime>json</test.mime>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
|
||||||
|
<!-- util -->
|
||||||
|
<guava.version>21.0</guava.version>
|
||||||
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
|
<commons-math3.version>3.6.1</commons-math3.version>
|
||||||
|
<commons-io.version>2.5</commons-io.version>
|
||||||
|
<commons-collections4.version>4.1</commons-collections4.version>
|
||||||
|
<collections-generic.version>4.01</collections-generic.version>
|
||||||
|
|
||||||
|
<!-- testing -->
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
<avaitility.version>1.7.0</avaitility.version>
|
||||||
|
|
||||||
|
</properties>
|
||||||
|
</project>
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.baeldung.concurrent.Scheduledexecutorservice;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class ScheduledExecutorServiceDemo {
|
||||||
|
|
||||||
|
public void execute() {
|
||||||
|
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
|
||||||
|
ScheduledFuture<?> scheduledFuture = executorService.schedule(() -> {
|
||||||
|
// Task
|
||||||
|
}, 1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
executorService.scheduleAtFixedRate(() -> {
|
||||||
|
// Task
|
||||||
|
}, 1, 10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
executorService.scheduleWithFixedDelay(() -> {
|
||||||
|
// Task
|
||||||
|
}, 1, 10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
Future<String> future = executorService.schedule(() -> {
|
||||||
|
// Task
|
||||||
|
return "Hellow world";
|
||||||
|
}, 1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
|
public class SafeCounterWithLock {
|
||||||
|
private volatile int counter;
|
||||||
|
|
||||||
|
int getValue() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized void increment() {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class SafeCounterWithoutLock {
|
||||||
|
private final AtomicInteger counter = new AtomicInteger(0);
|
||||||
|
|
||||||
|
int getValue() {
|
||||||
|
return counter.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment() {
|
||||||
|
while(true) {
|
||||||
|
int existingValue = getValue();
|
||||||
|
int newValue = existingValue + 1;
|
||||||
|
if(counter.compareAndSet(existingValue, newValue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
|
public class UnsafeCounter {
|
||||||
|
private int counter;
|
||||||
|
|
||||||
|
int getValue() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment() {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
@ -19,13 +19,15 @@ public class NumbersProducer implements Runnable {
|
|||||||
try {
|
try {
|
||||||
generateNumbers();
|
generateNumbers();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread()
|
||||||
|
.interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateNumbers() throws InterruptedException {
|
private void generateNumbers() throws InterruptedException {
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
numbersQueue.put(ThreadLocalRandom.current().nextInt(100));
|
numbersQueue.put(ThreadLocalRandom.current()
|
||||||
|
.nextInt(100));
|
||||||
}
|
}
|
||||||
for (int j = 0; j < poisonPillPerProducer; j++) {
|
for (int j = 0; j < poisonPillPerProducer; j++) {
|
||||||
numbersQueue.put(poisonPill);
|
numbersQueue.put(poisonPill);
|
@ -15,14 +15,12 @@ public class CyclicBarrierDemo {
|
|||||||
private int NUM_PARTIAL_RESULTS;
|
private int NUM_PARTIAL_RESULTS;
|
||||||
private int NUM_WORKERS;
|
private int NUM_WORKERS;
|
||||||
|
|
||||||
|
|
||||||
private void runSimulation(int numWorkers, int numberOfPartialResults) {
|
private void runSimulation(int numWorkers, int numberOfPartialResults) {
|
||||||
NUM_PARTIAL_RESULTS = numberOfPartialResults;
|
NUM_PARTIAL_RESULTS = numberOfPartialResults;
|
||||||
NUM_WORKERS = numWorkers;
|
NUM_WORKERS = numWorkers;
|
||||||
|
|
||||||
cyclicBarrier = new CyclicBarrier(NUM_WORKERS, new AggregatorThread());
|
cyclicBarrier = new CyclicBarrier(NUM_WORKERS, new AggregatorThread());
|
||||||
System.out.println("Spawning " + NUM_WORKERS + " worker threads to compute "
|
System.out.println("Spawning " + NUM_WORKERS + " worker threads to compute " + NUM_PARTIAL_RESULTS + " partial results each");
|
||||||
+ NUM_PARTIAL_RESULTS + " partial results each");
|
|
||||||
for (int i = 0; i < NUM_WORKERS; i++) {
|
for (int i = 0; i < NUM_WORKERS; i++) {
|
||||||
Thread worker = new Thread(new NumberCruncherThread());
|
Thread worker = new Thread(new NumberCruncherThread());
|
||||||
worker.setName("Thread " + i);
|
worker.setName("Thread " + i);
|
||||||
@ -38,8 +36,7 @@ public class CyclicBarrierDemo {
|
|||||||
List<Integer> partialResult = new ArrayList<>();
|
List<Integer> partialResult = new ArrayList<>();
|
||||||
for (int i = 0; i < NUM_PARTIAL_RESULTS; i++) {
|
for (int i = 0; i < NUM_PARTIAL_RESULTS; i++) {
|
||||||
Integer num = random.nextInt(10);
|
Integer num = random.nextInt(10);
|
||||||
System.out.println(thisThreadName
|
System.out.println(thisThreadName + ": Crunching some numbers! Final result - " + num);
|
||||||
+ ": Crunching some numbers! Final result - " + num);
|
|
||||||
partialResult.add(num);
|
partialResult.add(num);
|
||||||
}
|
}
|
||||||
partialResults.add(partialResult);
|
partialResults.add(partialResult);
|
||||||
@ -57,13 +54,12 @@ public class CyclicBarrierDemo {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
String thisThreadName = Thread.currentThread().getName();
|
String thisThreadName = Thread.currentThread().getName();
|
||||||
System.out.println(thisThreadName + ": Computing final sum of " + NUM_WORKERS
|
System.out.println(thisThreadName + ": Computing final sum of " + NUM_WORKERS + " workers, having " + NUM_PARTIAL_RESULTS + " results each.");
|
||||||
+ " workers, having " + NUM_PARTIAL_RESULTS + " results each.");
|
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for (List<Integer> threadResult : partialResults) {
|
for (List<Integer> threadResult : partialResults) {
|
||||||
System.out.print("Adding ");
|
System.out.print("Adding ");
|
||||||
for (Integer partialResult : threadResult) {
|
for (Integer partialResult : threadResult) {
|
||||||
System.out.print(partialResult+" ");
|
System.out.print(partialResult + " ");
|
||||||
sum += partialResult;
|
sum += partialResult;
|
||||||
}
|
}
|
||||||
System.out.println();
|
System.out.println();
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.concurrent.cyclicbarrier;
|
||||||
|
|
||||||
|
import java.util.concurrent.CyclicBarrier;
|
||||||
|
|
||||||
|
public class CyclicBarrierExample {
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
|
||||||
|
// Task
|
||||||
|
System.out.println("All previous tasks are completed");
|
||||||
|
});
|
||||||
|
|
||||||
|
Thread t1 = new Thread(new Task(cyclicBarrier), "T1");
|
||||||
|
Thread t2 = new Thread(new Task(cyclicBarrier), "T2");
|
||||||
|
Thread t3 = new Thread(new Task(cyclicBarrier), "T3");
|
||||||
|
|
||||||
|
if (!cyclicBarrier.isBroken()) {
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t3.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.concurrent.cyclicbarrier;
|
||||||
|
|
||||||
|
import java.util.concurrent.BrokenBarrierException;
|
||||||
|
import java.util.concurrent.CyclicBarrier;
|
||||||
|
|
||||||
|
public class Task implements Runnable {
|
||||||
|
|
||||||
|
private CyclicBarrier barrier;
|
||||||
|
|
||||||
|
public Task(CyclicBarrier barrier) {
|
||||||
|
this.barrier = barrier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
System.out.println("Thread : " + Thread.currentThread().getName() + " is waiting");
|
||||||
|
barrier.await();
|
||||||
|
System.out.println("Thread : " + Thread.currentThread().getName() + " is released");
|
||||||
|
} catch (InterruptedException | BrokenBarrierException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,9 +27,6 @@ public class DelayObject implements Delayed {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{" +
|
return "{" + "data='" + data + '\'' + ", startTime=" + startTime + '}';
|
||||||
"data='" + data + '\'' +
|
|
||||||
", startTime=" + startTime +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,7 +15,8 @@ public class Philosopher implements Runnable {
|
|||||||
Thread.sleep(((int) (Math.random() * 100)));
|
Thread.sleep(((int) (Math.random() * 100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void run() {
|
@Override
|
||||||
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
doAction(System.nanoTime() + ": Thinking"); // thinking
|
doAction(System.nanoTime() + ": Thinking"); // thinking
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.baeldung.concurrent.executor;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
public class ExecutorDemo {
|
||||||
|
|
||||||
|
public void execute() {
|
||||||
|
Executor executor = new Invoker();
|
||||||
|
executor.execute(()->{
|
||||||
|
// task to be performed
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.concurrent.executor;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
public class Invoker implements Executor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Runnable r) {
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.baeldung.concurrent.executorservice;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class ExecutorServiceDemo {
|
||||||
|
|
||||||
|
ExecutorService executor = Executors.newFixedThreadPool(10);
|
||||||
|
|
||||||
|
public void execute() {
|
||||||
|
|
||||||
|
executor.submit(() -> {
|
||||||
|
new Task();
|
||||||
|
});
|
||||||
|
|
||||||
|
executor.shutdown();
|
||||||
|
executor.shutdownNow();
|
||||||
|
try {
|
||||||
|
executor.awaitTermination(20l, TimeUnit.NANOSECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.concurrent.executorservice;
|
||||||
|
|
||||||
|
public class Task implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// task details
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.baeldung.concurrent.future;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
public class FutureDemo {
|
||||||
|
|
||||||
|
public String invoke() {
|
||||||
|
|
||||||
|
String str = null;
|
||||||
|
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(10);
|
||||||
|
|
||||||
|
Future<String> future = executorService.submit(() -> {
|
||||||
|
// Task
|
||||||
|
Thread.sleep(10000l);
|
||||||
|
return "Hellow world";
|
||||||
|
});
|
||||||
|
|
||||||
|
future.cancel(false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
future.get(20, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException | ExecutionException | TimeoutException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (future.isDone() && !future.isCancelled()) {
|
||||||
|
try {
|
||||||
|
str = future.get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.concurrent.semaphore;
|
||||||
|
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
|
public class SemaPhoreDemo {
|
||||||
|
|
||||||
|
static Semaphore semaphore = new Semaphore(10);
|
||||||
|
|
||||||
|
public void execute() throws InterruptedException {
|
||||||
|
|
||||||
|
System.out.println("Available permit : " + semaphore.availablePermits());
|
||||||
|
System.out.println("Number of threads waiting to acquire: " + semaphore.getQueueLength());
|
||||||
|
|
||||||
|
if (semaphore.tryAcquire()) {
|
||||||
|
semaphore.acquire();
|
||||||
|
// perform some critical operations
|
||||||
|
semaphore.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.concurrent.threadfactory;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
|
||||||
|
public class BaeldungThreadFactory implements ThreadFactory {
|
||||||
|
|
||||||
|
private int threadId;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public BaeldungThreadFactory(String name) {
|
||||||
|
threadId = 1;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
Thread t = new Thread(r, name + "-Thread_" + threadId);
|
||||||
|
System.out.println("created new thread with id : " + threadId + " and name : " + t.getName());
|
||||||
|
threadId++;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.concurrent.threadfactory;
|
||||||
|
|
||||||
|
public class Demo {
|
||||||
|
|
||||||
|
public void execute() {
|
||||||
|
BaeldungThreadFactory factory = new BaeldungThreadFactory("BaeldungThreadFactory");
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
Thread t = factory.newThread(new Task());
|
||||||
|
t.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.concurrent.threadfactory;
|
||||||
|
|
||||||
|
public class Task implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// task details
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.concurrent.volatilekeyword;
|
||||||
|
|
||||||
|
|
||||||
|
public class SharedObject {
|
||||||
|
private volatile int count=0;
|
||||||
|
|
||||||
|
void increamentCount(){
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
public int getCount(){
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
@ -4,14 +4,14 @@ package com.baeldung.threadlocal;
|
|||||||
public class Context {
|
public class Context {
|
||||||
private final String userName;
|
private final String userName;
|
||||||
|
|
||||||
public Context(String userName) {
|
Context(String userName) {
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Context{" +
|
return "Context{" +
|
||||||
"userNameSecret='" + userName + '\'' +
|
"userNameSecret='" + userName + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,11 +5,11 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class SharedMapWithUserContext implements Runnable {
|
public class SharedMapWithUserContext implements Runnable {
|
||||||
public final static Map<Integer, Context> userContextPerUserId = new ConcurrentHashMap<>();
|
final static Map<Integer, Context> userContextPerUserId = new ConcurrentHashMap<>();
|
||||||
private final Integer userId;
|
private final Integer userId;
|
||||||
private UserRepository userRepository = new UserRepository();
|
private UserRepository userRepository = new UserRepository();
|
||||||
|
|
||||||
public SharedMapWithUserContext(Integer userId) {
|
SharedMapWithUserContext(Integer userId) {
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ public class ThreadLocalWithUserContext implements Runnable {
|
|||||||
private final Integer userId;
|
private final Integer userId;
|
||||||
private UserRepository userRepository = new UserRepository();
|
private UserRepository userRepository = new UserRepository();
|
||||||
|
|
||||||
public ThreadLocalWithUserContext(Integer userId) {
|
ThreadLocalWithUserContext(Integer userId) {
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
|
|
||||||
public class UserRepository {
|
public class UserRepository {
|
||||||
public String getUserNameForUserId(Integer userId) {
|
String getUserNameForUserId(Integer userId) {
|
||||||
return UUID.randomUUID().toString();
|
return UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,19 +2,21 @@ package com.baeldung.threadpool;
|
|||||||
|
|
||||||
import java.util.concurrent.ForkJoinTask;
|
import java.util.concurrent.ForkJoinTask;
|
||||||
import java.util.concurrent.RecursiveTask;
|
import java.util.concurrent.RecursiveTask;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class CountingTask extends RecursiveTask<Integer> {
|
public class CountingTask extends RecursiveTask<Integer> {
|
||||||
|
|
||||||
private final TreeNode node;
|
private final TreeNode node;
|
||||||
|
|
||||||
public CountingTask(TreeNode node) {
|
CountingTask(TreeNode node) {
|
||||||
this.node = node;
|
this.node = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Integer compute() {
|
protected Integer compute() {
|
||||||
return node.value + node.children.stream().map(childNode -> new CountingTask(childNode).fork()).collect(Collectors.summingInt(ForkJoinTask::join));
|
return node.getValue() + node.getChildren().stream()
|
||||||
|
.map(childNode -> new CountingTask(childNode).fork())
|
||||||
|
.mapToInt(ForkJoinTask::join)
|
||||||
|
.sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.threadpool;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class TreeNode {
|
||||||
|
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
private Set<TreeNode> children;
|
||||||
|
|
||||||
|
TreeNode(int value, TreeNode... children) {
|
||||||
|
this.value = value;
|
||||||
|
this.children = Sets.newHashSet(children);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<TreeNode> getChildren() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
}
|
@ -9,13 +9,12 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
public class Consumer implements Runnable {
|
public class Consumer implements Runnable {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Consumer.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Consumer.class);
|
||||||
|
|
||||||
|
|
||||||
private final TransferQueue<String> transferQueue;
|
private final TransferQueue<String> transferQueue;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final int numberOfMessagesToConsume;
|
final int numberOfMessagesToConsume;
|
||||||
public final AtomicInteger numberOfConsumedMessages = new AtomicInteger();
|
final AtomicInteger numberOfConsumedMessages = new AtomicInteger();
|
||||||
|
|
||||||
public Consumer(TransferQueue<String> transferQueue, String name, int numberOfMessagesToConsume) {
|
Consumer(TransferQueue<String> transferQueue, String name, int numberOfMessagesToConsume) {
|
||||||
this.transferQueue = transferQueue;
|
this.transferQueue = transferQueue;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.numberOfMessagesToConsume = numberOfMessagesToConsume;
|
this.numberOfMessagesToConsume = numberOfMessagesToConsume;
|
@ -12,10 +12,10 @@ public class Producer implements Runnable {
|
|||||||
|
|
||||||
private final TransferQueue<String> transferQueue;
|
private final TransferQueue<String> transferQueue;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final Integer numberOfMessagesToProduce;
|
final Integer numberOfMessagesToProduce;
|
||||||
public final AtomicInteger numberOfProducedMessages = new AtomicInteger();
|
final AtomicInteger numberOfProducedMessages = new AtomicInteger();
|
||||||
|
|
||||||
public Producer(TransferQueue<String> transferQueue, String name, Integer numberOfMessagesToProduce) {
|
Producer(TransferQueue<String> transferQueue, String name, Integer numberOfMessagesToProduce) {
|
||||||
this.transferQueue = transferQueue;
|
this.transferQueue = transferQueue;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.numberOfMessagesToProduce = numberOfMessagesToProduce;
|
this.numberOfMessagesToProduce = numberOfMessagesToProduce;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user