Fix conflicts
This commit is contained in:
commit
9a9a0fc277
@ -106,3 +106,4 @@
|
||||
- [Converting a List to String in Java](http://www.baeldung.com/java-list-to-string)
|
||||
- [CharSequence vs. String in Java](http://www.baeldung.com/java-char-sequence-string)
|
||||
- [Period and Duration in Java](http://www.baeldung.com/java-period-duration)
|
||||
- [Guide to the Diamond Operator in Java](http://www.baeldung.com/java-diamond-operator)
|
@ -3,7 +3,7 @@
|
||||
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>
|
||||
|
||||
<artifactId>kotlin</artifactId>
|
||||
<artifactId>core-kotlin</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
3
geotools/README.md
Normal file
3
geotools/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
### Relevant Articles
|
||||
|
||||
[Introduction to GeoTools](http://www.baeldung.com/geo-tools)
|
@ -0,0 +1,39 @@
|
||||
package com.baeldung.pairs;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class CoreJavaSimpleEntryUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenSimpleEntry_whenGetValue_thenOk() {
|
||||
AbstractMap.SimpleEntry<Integer, String> entry = new AbstractMap.SimpleEntry<Integer, String>(1, "one");
|
||||
Integer key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
|
||||
assertEquals(key.intValue(), 1);
|
||||
assertEquals(value, "one");
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void givenSimpleImmutableEntry_whenSetValue_thenException() {
|
||||
AbstractMap.SimpleImmutableEntry<Integer, String> entry = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "one");
|
||||
|
||||
entry.setValue("two");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSimpleImmutableEntry_whenGetValue_thenOk() {
|
||||
AbstractMap.SimpleImmutableEntry<Integer, String> entry = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "one");
|
||||
Integer key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
|
||||
assertEquals(key.intValue(), 1);
|
||||
assertEquals(value, "one");
|
||||
}
|
||||
|
||||
}
|
3
linkrest/WebContent/META-INF/MANIFEST.MF
Normal file
3
linkrest/WebContent/META-INF/MANIFEST.MF
Normal file
@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
20
linkrest/WebContent/WEB-INF/web.xml
Normal file
20
linkrest/WebContent/WEB-INF/web.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
id="WebApp_ID" version="3.1">
|
||||
<display-name>linkrest</display-name>
|
||||
<servlet>
|
||||
<servlet-name>linkrest</servlet-name>
|
||||
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
|
||||
<init-param>
|
||||
<param-name>javax.ws.rs.Application</param-name>
|
||||
<param-value>com.baeldung.LinkRestApplication</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>linkrest</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app>
|
81
linkrest/pom.xml
Normal file
81
linkrest/pom.xml
Normal file
@ -0,0 +1,81 @@
|
||||
<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>linkrest</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.nhl.link.rest</groupId>
|
||||
<artifactId>link-rest</artifactId>
|
||||
<version>${linkrest.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.containers</groupId>
|
||||
<artifactId>jersey-container-servlet</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
<artifactId>jersey-media-moxy</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<configuration>
|
||||
<warSourceDirectory>WebContent</warSourceDirectory>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.cayenne.plugins</groupId>
|
||||
<artifactId>cayenne-maven-plugin</artifactId>
|
||||
<version>${cayenne.version}</version>
|
||||
|
||||
<configuration>
|
||||
<map>${project.basedir}/src/main/resources/linkrest.map.xml</map>
|
||||
</configuration>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>cgen</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.cayenne.plugins</groupId>
|
||||
<artifactId>cayenne-modeler-maven-plugin</artifactId>
|
||||
<version>${cayenne.version}</version>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
<properties>
|
||||
<linkrest.version>2.9</linkrest.version>
|
||||
<cayenne.version>4.0.B1</cayenne.version>
|
||||
<h2.version>1.4.196</h2.version>
|
||||
<jersey.version>2.25.1</jersey.version>
|
||||
</properties>
|
||||
</project>
|
24
linkrest/src/main/java/com/baeldung/LinkRestApplication.java
Normal file
24
linkrest/src/main/java/com/baeldung/LinkRestApplication.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.baeldung;
|
||||
|
||||
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
|
||||
import org.apache.cayenne.configuration.server.ServerRuntime;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import com.nhl.link.rest.runtime.LinkRestBuilder;
|
||||
import com.nhl.link.rest.runtime.LinkRestRuntime;
|
||||
|
||||
@ApplicationPath("/linkrest")
|
||||
public class LinkRestApplication extends ResourceConfig {
|
||||
|
||||
public LinkRestApplication() {
|
||||
ServerRuntime cayenneRuntime = ServerRuntime.builder()
|
||||
.addConfig("cayenne-linkrest-project.xml")
|
||||
.build();
|
||||
LinkRestRuntime lrRuntime = LinkRestBuilder.build(cayenneRuntime);
|
||||
super.register(lrRuntime);
|
||||
packages("com.baeldung.linkrest.apis");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.baeldung.cayenne;
|
||||
|
||||
import com.baeldung.cayenne.auto._Department;
|
||||
|
||||
public class Department extends _Department {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.baeldung.cayenne;
|
||||
|
||||
import com.baeldung.cayenne.auto._Employee;
|
||||
|
||||
public class Employee extends _Employee {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.baeldung.cayenne.auto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cayenne.CayenneDataObject;
|
||||
import org.apache.cayenne.exp.Property;
|
||||
|
||||
import com.baeldung.cayenne.Employee;
|
||||
|
||||
/**
|
||||
* Class _Department was generated by Cayenne.
|
||||
* It is probably a good idea to avoid changing this class manually,
|
||||
* since it may be overwritten next time code is regenerated.
|
||||
* If you need to make any customizations, please use subclass.
|
||||
*/
|
||||
public abstract class _Department extends CayenneDataObject {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String DEP_ID_PK_COLUMN = "dep_id";
|
||||
|
||||
public static final Property<String> NAME = Property.create("name", String.class);
|
||||
public static final Property<List<Employee>> EMPLOYEES = Property.create("employees", List.class);
|
||||
|
||||
public void setName(String name) {
|
||||
writeProperty("name", name);
|
||||
}
|
||||
public String getName() {
|
||||
return (String)readProperty("name");
|
||||
}
|
||||
|
||||
public void addToEmployees(Employee obj) {
|
||||
addToManyTarget("employees", obj, true);
|
||||
}
|
||||
public void removeFromEmployees(Employee obj) {
|
||||
removeToManyTarget("employees", obj, true);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Employee> getEmployees() {
|
||||
return (List<Employee>)readProperty("employees");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.baeldung.cayenne.auto;
|
||||
|
||||
import org.apache.cayenne.CayenneDataObject;
|
||||
import org.apache.cayenne.exp.Property;
|
||||
|
||||
import com.baeldung.cayenne.Department;
|
||||
|
||||
/**
|
||||
* Class _Employee was generated by Cayenne.
|
||||
* It is probably a good idea to avoid changing this class manually,
|
||||
* since it may be overwritten next time code is regenerated.
|
||||
* If you need to make any customizations, please use subclass.
|
||||
*/
|
||||
public abstract class _Employee extends CayenneDataObject {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String EMP_ID_PK_COLUMN = "emp_id";
|
||||
|
||||
public static final Property<String> NAME = Property.create("name", String.class);
|
||||
public static final Property<Department> DEPARTMENT = Property.create("department", Department.class);
|
||||
|
||||
public void setName(String name) {
|
||||
writeProperty("name", name);
|
||||
}
|
||||
public String getName() {
|
||||
return (String)readProperty("name");
|
||||
}
|
||||
|
||||
public void setDepartment(Department department) {
|
||||
setToOneTarget("department", department, true);
|
||||
}
|
||||
|
||||
public Department getDepartment() {
|
||||
return (Department)readProperty("department");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.baeldung.linkrest.apis;
|
||||
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Configuration;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import com.baeldung.cayenne.Department;
|
||||
import com.nhl.link.rest.DataResponse;
|
||||
import com.nhl.link.rest.LinkRest;
|
||||
import com.nhl.link.rest.SimpleResponse;
|
||||
|
||||
@Path("department")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public class DepartmentResource {
|
||||
|
||||
@Context
|
||||
private Configuration config;
|
||||
|
||||
@GET
|
||||
public DataResponse<Department> getAll(@Context UriInfo uriInfo) {
|
||||
return LinkRest.select(Department.class, config).uri(uriInfo).get();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
public DataResponse<Department> getOne(@PathParam("id") int id, @Context UriInfo uriInfo) {
|
||||
return LinkRest.select(Department.class, config).byId(id).uri(uriInfo).getOne();
|
||||
}
|
||||
|
||||
@POST
|
||||
public SimpleResponse create(String data) {
|
||||
return LinkRest.create(Department.class, config).sync(data);
|
||||
}
|
||||
|
||||
@PUT
|
||||
public SimpleResponse createOrUpdate(String data) {
|
||||
return LinkRest.createOrUpdate(Department.class, config).sync(data);
|
||||
}
|
||||
|
||||
@Path("{id}/employees")
|
||||
public EmployeeSubResource getEmployees(@PathParam("id") int id, @Context UriInfo uriInfo) {
|
||||
return new EmployeeSubResource(id, config);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{id}")
|
||||
public SimpleResponse delete(@PathParam("id") int id) {
|
||||
return LinkRest.delete(Department.class, config).id(id).delete();
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package com.baeldung.linkrest.apis;
|
||||
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Configuration;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import com.baeldung.cayenne.Department;
|
||||
import com.baeldung.cayenne.Employee;
|
||||
import com.nhl.link.rest.DataResponse;
|
||||
import com.nhl.link.rest.LinkRest;
|
||||
import com.nhl.link.rest.SimpleResponse;
|
||||
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public class EmployeeSubResource {
|
||||
|
||||
private Configuration config;
|
||||
|
||||
private int departmentId;
|
||||
|
||||
public EmployeeSubResource(int departmentId, Configuration config) {
|
||||
this.departmentId = departmentId;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public EmployeeSubResource() {
|
||||
}
|
||||
|
||||
@GET
|
||||
public DataResponse<Employee> getAll(@Context UriInfo uriInfo) {
|
||||
return LinkRest.select(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).uri(uriInfo).get();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
public DataResponse<Employee> getOne(@PathParam("id") int id, @Context UriInfo uriInfo) {
|
||||
return LinkRest.select(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).byId(id).uri(uriInfo).getOne();
|
||||
}
|
||||
|
||||
@POST
|
||||
public SimpleResponse create(String data) {
|
||||
|
||||
return LinkRest.create(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).sync(data);
|
||||
}
|
||||
|
||||
@PUT
|
||||
public SimpleResponse createOrUpdate(String data) {
|
||||
return LinkRest.create(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).sync(data);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{id}")
|
||||
public SimpleResponse delete(@PathParam("id") int id) {
|
||||
return LinkRest.delete(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).id(id).delete();
|
||||
|
||||
}
|
||||
|
||||
}
|
17
linkrest/src/main/resources/cayenne-linkrest-project.xml
Normal file
17
linkrest/src/main/resources/cayenne-linkrest-project.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<domain project-version="9">
|
||||
<map name="linkrest"/>
|
||||
|
||||
<node name="datanode"
|
||||
factory="org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory"
|
||||
schema-update-strategy="org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy"
|
||||
>
|
||||
<map-ref name="linkrest"/>
|
||||
<data-source>
|
||||
<driver value="org.h2.Driver"/>
|
||||
<url value="jdbc:h2:mem:myDb;MVCC=TRUE"/>
|
||||
<connectionPool min="1" max="1"/>
|
||||
<login userName="sa" password="sa"/>
|
||||
</data-source>
|
||||
</node>
|
||||
</domain>
|
29
linkrest/src/main/resources/linkrest.map.xml
Normal file
29
linkrest/src/main/resources/linkrest.map.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<data-map xmlns="http://cayenne.apache.org/schema/9/modelMap"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://cayenne.apache.org/schema/9/modelMap http://cayenne.apache.org/schema/9/modelMap.xsd"
|
||||
project-version="9">
|
||||
<property name="defaultPackage" value="com.baeldung.cayenne"/>
|
||||
<db-entity name="departments">
|
||||
<db-attribute name="dep_id" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
|
||||
<db-attribute name="name" type="NVARCHAR" length="50"/>
|
||||
</db-entity>
|
||||
<db-entity name="employees">
|
||||
<db-attribute name="emp_id" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
|
||||
<db-attribute name="name" type="NVARCHAR" length="50"/>
|
||||
</db-entity>
|
||||
<obj-entity name="Department" className="com.baeldung.cayenne.Department" dbEntityName="departments">
|
||||
<obj-attribute name="name" type="java.lang.String" db-attribute-path="name"/>
|
||||
</obj-entity>
|
||||
<obj-entity name="Employee" className="com.baeldung.cayenne.Employee" dbEntityName="employees">
|
||||
<obj-attribute name="name" type="java.lang.String" db-attribute-path="name"/>
|
||||
</obj-entity>
|
||||
<db-relationship name="employees" source="departments" target="employees" toMany="true">
|
||||
<db-attribute-pair source="dep_id" target="emp_id"/>
|
||||
</db-relationship>
|
||||
<db-relationship name="department" source="employees" target="departments" toDependentPK="true" toMany="false">
|
||||
<db-attribute-pair source="emp_id" target="dep_id"/>
|
||||
</db-relationship>
|
||||
<obj-relationship name="employees" source="Department" target="Employee" deleteRule="Deny" db-relationship-path="employees"/>
|
||||
<obj-relationship name="department" source="Employee" target="Department" deleteRule="Nullify" db-relationship-path="department"/>
|
||||
</data-map>
|
1
pom.xml
1
pom.xml
@ -99,6 +99,7 @@
|
||||
|
||||
<module>libraries</module>
|
||||
<module>libraries-data</module>
|
||||
<module>linkrest</module>
|
||||
<module>log-mdc</module>
|
||||
<module>log4j</module>
|
||||
<module>log4j2</module>
|
||||
|
@ -3,8 +3,7 @@ package org.baeldung.controller.controller;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
@ -16,20 +15,20 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
*/
|
||||
@Controller
|
||||
public class PassParametersController {
|
||||
@RequestMapping(value = "/showViewPage", method = RequestMethod.GET)
|
||||
@GetMapping("/showViewPage")
|
||||
public String passParametersWithModel(Model model) {
|
||||
model.addAttribute("message", "Baeldung");
|
||||
return "viewPage";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/printViewPage", method = RequestMethod.GET)
|
||||
@GetMapping("/printViewPage")
|
||||
public String passParametersWithModelMap(ModelMap map) {
|
||||
map.addAttribute("welcomeMessage", "welcome");
|
||||
map.addAttribute("message", "Baeldung");
|
||||
return "viewPage";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/goToViewPage", method = RequestMethod.GET)
|
||||
@GetMapping("/goToViewPage")
|
||||
public ModelAndView passParametersWithModelAndView() {
|
||||
ModelAndView modelAndView = new ModelAndView("viewPage");
|
||||
modelAndView.addObject("message", "Baeldung");
|
||||
|
@ -15,6 +15,7 @@
|
||||
<module>spring-cloud-ribbon-client</module>
|
||||
<module>spring-cloud-rest</module>
|
||||
<module>spring-cloud-zookeeper</module>
|
||||
<module>spring-cloud-gateway</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
2
spring-cloud/spring-cloud-gateway/README.MD
Normal file
2
spring-cloud/spring-cloud-gateway/README.MD
Normal file
@ -0,0 +1,2 @@
|
||||
### Relevant Articles:
|
||||
- [Explore the new Spring Cloud Gateway](http://www.baeldung.com/spring-cloud-gateway)
|
79
spring-cloud/spring-cloud-gateway/gateway-service/pom.xml
Normal file
79
spring-cloud/spring-cloud-gateway/gateway-service/pom.xml
Normal file
@ -0,0 +1,79 @@
|
||||
<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>
|
||||
|
||||
<artifactId>gateway-service</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Spring Cloud Gateway Service</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.spring.cloud</groupId>
|
||||
<artifactId>spring-cloud-gateway</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<version>2.0.0.M2</version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator</artifactId>
|
||||
<version>${version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<version>${version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gateway-core</artifactId>
|
||||
<version>${version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-eureka</artifactId>
|
||||
<version>${version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator-cdi</artifactId>
|
||||
<version>6.0.2.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>2.0.0.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor.ipc</groupId>
|
||||
<artifactId>reactor-netty</artifactId>
|
||||
<version>0.7.0.M1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
@ -0,0 +1,12 @@
|
||||
package com.baeldung.spring.cloud;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class GatewayApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GatewayApplication.class, args);
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
server:
|
||||
port: 80
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: baeldung_route
|
||||
uri: http://www.baeldung.com
|
||||
predicates:
|
||||
- Path=/baeldung
|
||||
management:
|
||||
security:
|
||||
enabled: false
|
50
spring-cloud/spring-cloud-gateway/pom.xml
Normal file
50
spring-cloud/spring-cloud-gateway/pom.xml
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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.spring.cloud</groupId>
|
||||
<artifactId>spring-cloud-gateway</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<modules>
|
||||
<module>gateway-service</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Cloud Gateway</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.spring.cloud</groupId>
|
||||
<artifactId>spring-cloud</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||
<spring-boot-maven-plugin.version>1.4.2.RELEASE</spring-boot-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
@ -74,7 +74,7 @@
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<vavr.version>0.9.0</vavr.version>
|
||||
<vavr.version>0.9.1</vavr.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<awaitility.version>3.0.0</awaitility.version>
|
||||
</properties>
|
||||
|
@ -5,17 +5,23 @@ import static io.vavr.API.Case;
|
||||
import static io.vavr.API.Match;
|
||||
import static io.vavr.Predicates.exists;
|
||||
import static io.vavr.Predicates.forAll;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.internal.verification.VerificationModeFactory;
|
||||
import org.mockito.verification.Timeout;
|
||||
|
||||
import io.vavr.Tuple;
|
||||
import io.vavr.Tuple2;
|
||||
import io.vavr.collection.List;
|
||||
import io.vavr.concurrent.Future;
|
||||
import io.vavr.control.Try;
|
||||
|
||||
public class FutureUnitTest {
|
||||
|
||||
@ -26,8 +32,7 @@ public class FutureUnitTest {
|
||||
public void givenFunctionReturnInteger_WhenCallWithFuture_ShouldReturnFunctionValue() {
|
||||
Future<Integer> future = Future.of(() -> 1);
|
||||
|
||||
assertEquals(1, future.get()
|
||||
.intValue());
|
||||
assertEquals(1, future.get().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -57,33 +62,29 @@ public class FutureUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenFunction_WhenCallWithFutureAndRegisterConsumerForSuccess_ShouldCallConsumerToStoreValue() {
|
||||
final int[] store = new int[] { 0 };
|
||||
Future<Integer> future = Future.of(() -> 1);
|
||||
future.onSuccess(i -> {
|
||||
store[0] = i;
|
||||
});
|
||||
await().until(() -> store[0] == 1);
|
||||
MockConsumer consumer = Mockito.mock(MockConsumer.class);
|
||||
future.onSuccess(consumer);
|
||||
Mockito.verify(consumer, new Timeout(1000, VerificationModeFactory.times(1))).accept(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFunctionThrowException_WhenCallWithFutureAndRegisterConsumerForFailer_ShouldCallConsumerToStoreException() {
|
||||
final Throwable[] store = new Throwable[] { null };
|
||||
Future<String> future = Future.of(() -> getResourceThrowException(""));
|
||||
future.onFailure(err -> store[0] = err);
|
||||
await().until(() -> RuntimeException.class.isInstance(store[0]));
|
||||
MockThrowableConsumer consumer = Mockito.mock(MockThrowableConsumer.class);
|
||||
future.onFailure(consumer);
|
||||
Mockito.verify(consumer, new Timeout(1000, VerificationModeFactory.times(1))).accept(Mockito.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAFuture_WhenAddAndThenConsumer_ShouldCallConsumerWithResultOfFutureAction() {
|
||||
int[] store1 = new int[1];
|
||||
int[] store2 = new int[1];
|
||||
MockTryConsumer consumer1 = Mockito.mock(MockTryConsumer.class);
|
||||
MockTryConsumer consumer2 = Mockito.mock(MockTryConsumer.class);
|
||||
Future<Integer> future = Future.of(() -> 1);
|
||||
Future<Integer> andThenFuture = future.andThen(i -> store1[0] = i.get() + 1)
|
||||
.andThen(i -> store2[0] = store1[0] + 1);
|
||||
Future<Integer> andThenFuture = future.andThen(consumer1).andThen(consumer2);
|
||||
andThenFuture.await();
|
||||
|
||||
assertEquals(2, store1[0]);
|
||||
assertEquals(3, store2[0]);
|
||||
Mockito.verify(consumer1, VerificationModeFactory.times(1)).accept(Try.success(1));
|
||||
Mockito.verify(consumer2, VerificationModeFactory.times(1)).accept(Try.success(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -91,8 +92,7 @@ public class FutureUnitTest {
|
||||
Future<Integer> future = Future.failed(new RuntimeException());
|
||||
Future<Integer> future2 = future.orElse(Future.of(() -> 2));
|
||||
|
||||
assertEquals(2, future2.get()
|
||||
.intValue());
|
||||
assertEquals(2, future2.get().intValue());
|
||||
}
|
||||
|
||||
@Test(expected = CancellationException.class)
|
||||
@ -124,17 +124,46 @@ public class FutureUnitTest {
|
||||
Future<String> future = Future.failed(new RuntimeException());
|
||||
Future<String> fallbackFuture = Future.of(() -> expectedResult);
|
||||
Future<String> futureResult = future.fallbackTo(fallbackFuture);
|
||||
futureResult.await();
|
||||
|
||||
assertEquals(expectedResult, futureResult.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAFuture_WhenTransformByAddingOne_ShouldReturn() {
|
||||
Future<Object> future = Future.of(() -> 1).transformValue(f -> Try.of(() -> "Hello: " + f.get()));
|
||||
|
||||
assertEquals("Hello: 1", future.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAFutureOfInt_WhenMapToString_ShouldCombineAndReturn() {
|
||||
Future<String> future = Future.of(()->1).map(i -> "Hello: " + i);
|
||||
|
||||
assertEquals("Hello: 1", future.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAFutureOfInt_WhenFlatMapToString_ShouldCombineAndReturn() {
|
||||
Future<Object> futureMap = Future.of(() -> 1).flatMap((i) -> Future.of(() -> "Hello: " + i));
|
||||
|
||||
assertEquals("Hello: 1", futureMap.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAFutureOf2String_WhenZip_ShouldReturnTupleOf2String() {
|
||||
Future<Tuple2<String, String>> future = Future.of(() -> "hello").zip(Future.of(() -> "world"));
|
||||
|
||||
assertEquals(Tuple.of("hello", "world"), future.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenGetResourceWithFuture_WhenWaitAndMatchWithPredicate_ShouldReturnSuccess() {
|
||||
String url = "http://resource";
|
||||
Future<String> future = Future.of(() -> getResource(url));
|
||||
future.await();
|
||||
String s = Match(future).of(Case($(future0 -> future0.isSuccess()), SUCCESS), Case($(), FAILURE));
|
||||
String s = Match(future).of(
|
||||
Case($(future0 -> future0.isSuccess()), SUCCESS),
|
||||
Case($(), FAILURE));
|
||||
|
||||
assertEquals(SUCCESS, s);
|
||||
}
|
||||
@ -143,7 +172,9 @@ public class FutureUnitTest {
|
||||
public void givenAFailedFuture_WhenWaitAndMatchWithPredicateCheckSuccess_ShouldReturnFailed() {
|
||||
Future<Integer> future = Future.failed(new RuntimeException());
|
||||
future.await();
|
||||
String s = Match(future).of(Case($(future0 -> future0.isSuccess()), SUCCESS), Case($(), FAILURE));
|
||||
String s = Match(future).of(
|
||||
Case($(future0 -> future0.isSuccess()), SUCCESS),
|
||||
Case($(), FAILURE));
|
||||
|
||||
assertEquals(FAILURE, s);
|
||||
}
|
||||
@ -155,7 +186,10 @@ public class FutureUnitTest {
|
||||
return 1;
|
||||
});
|
||||
Predicate<Future<Integer>> predicate = f -> f.exists(i -> i % 2 == 1);
|
||||
String s = Match(future).of(Case($(predicate), "Even"), Case($(), "Odd"));
|
||||
|
||||
String s = Match(future).of(
|
||||
Case($(predicate), "Even"),
|
||||
Case($(), "Odd"));
|
||||
|
||||
assertEquals("Even", s);
|
||||
}
|
||||
@ -164,7 +198,9 @@ public class FutureUnitTest {
|
||||
public void givenAListOfFutureReturnFist3Integers_WhenMatchWithExistEvenNumberPredicate_ShouldReturnSuccess() {
|
||||
List<Future<Integer>> futures = getFutureOfFirst3Number();
|
||||
Predicate<Future<Integer>> predicate0 = future -> future.exists(i -> i % 2 == 0);
|
||||
String s = Match(futures).of(Case($(exists(predicate0)), "Even"), Case($(), "Odd"));
|
||||
String s = Match(futures).of(
|
||||
Case($(exists(predicate0)), "Even"),
|
||||
Case($(), "Odd"));
|
||||
|
||||
assertEquals("Even", s);
|
||||
}
|
||||
@ -173,7 +209,9 @@ public class FutureUnitTest {
|
||||
public void givenAListOfFutureReturnFist3Integers_WhenMatchWithForAllNumberBiggerThanZeroPredicate_ShouldReturnSuccess() {
|
||||
List<Future<Integer>> futures = getFutureOfFirst3Number();
|
||||
Predicate<Future<Integer>> predicate0 = future -> future.exists(i -> i > 0);
|
||||
String s = Match(futures).of(Case($(forAll(predicate0)), "Positive numbers"), Case($(), "None"));
|
||||
String s = Match(futures).of(
|
||||
Case($(forAll(predicate0)), "Positive numbers"),
|
||||
Case($(), "None"));
|
||||
|
||||
assertEquals("Positive numbers", s);
|
||||
}
|
||||
@ -182,13 +220,19 @@ public class FutureUnitTest {
|
||||
public void givenAListOfFutureReturnFist3Integers_WhenMatchWithForAllNumberSmallerThanZeroPredicate_ShouldReturnFailed() {
|
||||
List<Future<Integer>> futures = getFutureOfFirst3Number();
|
||||
Predicate<Future<Integer>> predicate0 = future -> future.exists(i -> i < 0);
|
||||
String s = Match(futures).of(Case($(forAll(predicate0)), "Negative numbers"), Case($(), "None"));
|
||||
String s = Match(futures).of(
|
||||
Case($(forAll(predicate0)), "Negative numbers"),
|
||||
Case($(), "None"));
|
||||
|
||||
assertEquals("None", s);
|
||||
}
|
||||
|
||||
private String getResource(String url) throws InterruptedException {
|
||||
Thread.sleep(10);
|
||||
private String getResource(String url) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return "Content from " + url;
|
||||
}
|
||||
|
||||
@ -200,4 +244,46 @@ public class FutureUnitTest {
|
||||
List<Future<Integer>> futures = List.of(Future.of(() -> 1), Future.of(() -> 2), Future.of(() -> 3));
|
||||
return futures;
|
||||
}
|
||||
|
||||
private static void checkOnSuccessFunction() {
|
||||
Future<Integer> future = Future.of(() -> 1);
|
||||
future.onSuccess(i -> System.out.println("Future finish with result: " + i));
|
||||
}
|
||||
|
||||
private static void checkOnFailureFunction() {
|
||||
Future<Integer> future = Future.of(() -> {throw new RuntimeException("Failed");});
|
||||
future.onFailure(t -> System.out.println("Future failures with exception: " + t));
|
||||
}
|
||||
|
||||
private static void runAndThenConsumer() {
|
||||
Future<Integer> future = Future.of(() -> 1);
|
||||
future.andThen(i -> System.out.println("Do side-effect action 1 with input: " + i.get())).
|
||||
andThen((i) -> System.out.println("Do side-effect action 2 with input: " + i.get()));
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
checkOnSuccessFunction();
|
||||
checkOnFailureFunction();
|
||||
runAndThenConsumer();
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MockConsumer implements Consumer<Integer> {
|
||||
@Override
|
||||
public void accept(Integer t) {
|
||||
}
|
||||
}
|
||||
|
||||
class MockTryConsumer implements Consumer<Try<Integer>> {
|
||||
@Override
|
||||
public void accept(Try<Integer> t) {
|
||||
}
|
||||
}
|
||||
|
||||
class MockThrowableConsumer implements Consumer<Throwable> {
|
||||
@Override
|
||||
public void accept(Throwable t) {
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user