diff --git a/apache-olingo/olingo2/pom.xml b/apache-olingo/olingo2/pom.xml index 4fc81e5e49..1efd4ea602 100644 --- a/apache-olingo/olingo2/pom.xml +++ b/apache-olingo/olingo2/pom.xml @@ -44,11 +44,6 @@ spring-boot-configuration-processor true - - org.projectlombok - lombok - true - org.springframework.boot spring-boot-starter-test @@ -68,16 +63,6 @@ - - org.apache.olingo - olingo-odata2-api - ${olingo2.version} - - - org.apache.olingo - olingo-odata2-jpa-processor-api - ${olingo2.version} - org.apache.olingo olingo-odata2-jpa-processor-core diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java index 42a3eaa59d..e66d266062 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java @@ -12,25 +12,104 @@ import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.NotNull; -import lombok.Data; - @Entity -@Data -@Table(name="car_maker") +@Table(name = "car_maker") public class CarMaker { - + @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - + @NotNull - @Column(name="name") + @Column(name = "name") private String name; - - @OneToMany(mappedBy="maker", - orphanRemoval = true, - cascade=CascadeType.ALL) + + @OneToMany(mappedBy = "maker", orphanRemoval = true, cascade = CascadeType.ALL) private List models; - + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the models + */ + public List getModels() { + return models; + } + + /** + * @param models the models to set + */ + public void setModels(List models) { + this.models = models; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((models == null) ? 0 : models.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CarMaker other = (CarMaker) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (models == null) { + if (other.models != null) + return false; + } else if (!models.equals(other.models)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } } diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java index a4f2a04f6e..f9f563e01e 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java @@ -1,6 +1,5 @@ package org.baeldung.examples.olingo2.domain; - import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; @@ -11,28 +10,150 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.validation.constraints.NotNull; -import lombok.Data; - @Entity -@Data -@Table(name="car_model") +@Table(name = "car_model") public class CarModel { @Id - @GeneratedValue(strategy=GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.AUTO) private Long id; - + @NotNull private String name; - + @NotNull private Integer year; - + @NotNull private String sku; - - @ManyToOne(optional=false, fetch= FetchType.LAZY) - @JoinColumn(name="maker_fk") + + @ManyToOne(optional = false, fetch = FetchType.LAZY) + @JoinColumn(name = "maker_fk") private CarMaker maker; + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the year + */ + public Integer getYear() { + return year; + } + + /** + * @param year the year to set + */ + public void setYear(Integer year) { + this.year = year; + } + + /** + * @return the sku + */ + public String getSku() { + return sku; + } + + /** + * @param sku the sku to set + */ + public void setSku(String sku) { + this.sku = sku; + } + + /** + * @return the maker + */ + public CarMaker getMaker() { + return maker; + } + + /** + * @param maker the maker to set + */ + public void setMaker(CarMaker maker) { + this.maker = maker; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((maker == null) ? 0 : maker.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((sku == null) ? 0 : sku.hashCode()); + result = prime * result + ((year == null) ? 0 : year.hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CarModel other = (CarModel) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (maker == null) { + if (other.maker != null) + return false; + } else if (!maker.equals(other.maker)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (sku == null) { + if (other.sku != null) + return false; + } else if (!sku.equals(other.sku)) + return false; + if (year == null) { + if (other.year != null) + return false; + } else if (!year.equals(other.year)) + return false; + return true; + } + } diff --git a/apache-olingo/olingo2/src/main/resources/application.yml b/apache-olingo/olingo2/src/main/resources/application.yml index 21563a94fe..71df0c4166 100644 --- a/apache-olingo/olingo2/src/main/resources/application.yml +++ b/apache-olingo/olingo2/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 8180 + port: 8080 spring: jersey: diff --git a/apache-olingo/olingo4/.gitignore b/apache-olingo/olingo4/.gitignore deleted file mode 100644 index 153c9335eb..0000000000 --- a/apache-olingo/olingo4/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -HELP.md -/target/ -!.mvn/wrapper/maven-wrapper.jar - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -/build/ - -### VS Code ### -.vscode/ diff --git a/apache-olingo/olingo4/pom.xml b/apache-olingo/olingo4/pom.xml deleted file mode 100644 index 794aee0711..0000000000 --- a/apache-olingo/olingo4/pom.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.1.3.RELEASE - - - org.baeldung.examples.olingo4 - olingo4-sample - 0.0.1-SNAPSHOT - olingo4-sample - Sample Olingo 4 Project - - - 1.8 - 4.5.0 - - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - com.h2database - h2 - runtime - - - - org.projectlombok - lombok - true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-web - - - - org.apache.olingo - odata-server-api - ${odata.version} - - - org.apache.olingo - odata-server-core - ${odata.version} - runtime - - - - org.apache.olingo - odata-commons-api - ${odata.version} - - - org.apache.olingo - odata-commons-core - ${odata.version} - - - - commons-beanutils - commons-beanutils - 1.9.3 - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java deleted file mode 100644 index 18f7f8ba24..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.baeldung.examples.olingo4; - -import org.apache.olingo.server.api.OData; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.stereotype.Component; - -/** - * Default implementation for ODataFactory - * @author Philippe - * - */ -@Component -public class DefaultODataFactory implements ODataFactory { - - @Override - public OData newInstance() { - return OData.newInstance(); - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java deleted file mode 100644 index 9acb4b8c5e..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.baeldung.examples.olingo4; - -import org.apache.olingo.server.api.OData; - -public interface ODataFactory { - - public OData newInstance(); -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java deleted file mode 100644 index 27d0737c24..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.baeldung.examples.olingo4; - -import org.apache.olingo.server.api.ODataHttpHandler; - -public interface ODataHttpHandlerFactory { - - ODataHttpHandler newInstance(); -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java deleted file mode 100644 index 68d39dc052..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.baeldung.examples.olingo4; - -import java.util.Collections; -import java.util.List; - -import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider; -import org.apache.olingo.server.api.OData; -import org.apache.olingo.server.api.ODataHttpHandler; -import org.apache.olingo.server.api.ServiceMetadata; -import org.apache.olingo.server.api.processor.Processor; - -import lombok.Builder; - -@Builder -public class ODataHttpHandlerFactoryImpl implements ODataHttpHandlerFactory { - - - private final ODataFactory odataFactory; - private final CsdlEdmProvider edmProvider; - private final List processors; - - public ODataHttpHandlerFactoryImpl(ODataFactory odataFactory,CsdlEdmProvider edmProvider, List processors) { - this.odataFactory = odataFactory; - this.edmProvider = edmProvider; - this.processors = processors; - } - - @Override - public ODataHttpHandler newInstance() { - - OData odata = odataFactory.newInstance(); - ServiceMetadata metadata = odata.createServiceMetadata(edmProvider, Collections.emptyList()); - ODataHttpHandler handler = odata.createHandler(metadata); - - // Register all available processors - processors.forEach(p -> handler.register(p)); - - - return handler; - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java deleted file mode 100644 index 0cde665359..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.baeldung.examples.olingo4; - -import java.util.List; - -import javax.persistence.EntityManagerFactory; -import javax.servlet.http.HttpServlet; - -import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider; -import org.apache.olingo.server.api.processor.Processor; -import org.baeldung.examples.olingo4.ODataHttpHandlerFactoryImpl.ODataHttpHandlerFactoryImplBuilder; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class ODataServiceConfiguration { - - @Bean - public ServletRegistrationBean odataServletRegistration(ODataHttpHandlerFactory factory) { - ServletRegistrationBean srb = - new ServletRegistrationBean<>(new ODataServlet(factory), "/odata/*"); - srb.setLoadOnStartup(1); - return srb; - } - - @Bean - public ODataHttpHandlerFactory httpHandlerFactory(CsdlEdmProvider edmProvider, ODataFactory odataFactory, List processors) { - return new ODataHttpHandlerFactoryImplBuilder() - .edmProvider(edmProvider) - .odataFactory(odataFactory) - .processors(processors) - .build(); - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java deleted file mode 100644 index c379124541..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * - */ -package org.baeldung.examples.olingo4; - -import java.io.IOException; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.olingo.server.api.ODataHttpHandler; - -/** - * @author Philippe - * - */ -public class ODataServlet extends HttpServlet { - - private static final long serialVersionUID = 1L; - private final ODataHttpHandlerFactory odataHttpHandlerFactory; - - - public ODataServlet(ODataHttpHandlerFactory factory) { - this.odataHttpHandlerFactory = factory; - } - - @Override - protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - - ODataHttpHandler handler = odataHttpHandlerFactory.newInstance(); - handler.process(req, resp); - } -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java deleted file mode 100644 index 79825b4556..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.baeldung.examples.olingo4.domain; - -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.validation.constraints.NotNull; - -import lombok.Data; - -@Entity -@Data -@Table(name="car_maker") -public class CarMaker { - - @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - private Long id; - - @NotNull - @Column(name="name") - private String name; - - @OneToMany(mappedBy="maker", - orphanRemoval = true, - cascade=CascadeType.ALL) - private List models; - - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java deleted file mode 100644 index a9254e48b9..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.baeldung.examples.olingo4.domain; - - -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.validation.constraints.NotNull; - -import lombok.Data; - -@Entity -@Data -@Table(name="car_model") -public class CarModel { - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - private Long id; - - @NotNull - private String name; - - @NotNull - private Integer year; - - @NotNull - private String sku; - - @ManyToOne(optional=false, fetch= FetchType.EAGER ) - @JoinColumn(name="maker_fk") - private CarMaker maker; - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java deleted file mode 100644 index 95797752a2..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.baeldung.examples.olingo4.edm; - -import java.util.Collections; -import java.util.Date; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.sql.Time; -import java.util.AbstractMap.SimpleEntry; - -import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; -import org.springframework.stereotype.Component; - -@Component -public class EdmTypeMapper { - - public EdmPrimitiveTypeKind java2edm(Class clazz) { - EdmPrimitiveTypeKind result = java2edm.get(clazz); - if ( result == null ) { - throw new IllegalArgumentException("[E19] Unsupported class mapping: class=" + clazz); - } - else { - return result; - } - } - - // Static map used generate attribute metadada based on Java types - static Map,EdmPrimitiveTypeKind> java2edm = Collections - .unmodifiableMap(Stream.of( - new SimpleEntry<>(Boolean.class,EdmPrimitiveTypeKind.Boolean), - new SimpleEntry<>(Byte.class,EdmPrimitiveTypeKind.SByte), - new SimpleEntry<>(Date.class,EdmPrimitiveTypeKind.Date), - new SimpleEntry<>(Time.class,EdmPrimitiveTypeKind.TimeOfDay), - new SimpleEntry<>(Number.class,EdmPrimitiveTypeKind.Decimal), - new SimpleEntry<>(Float.class,EdmPrimitiveTypeKind.Single), - new SimpleEntry<>(Double.class,EdmPrimitiveTypeKind.Double), - new SimpleEntry<>(UUID.class,EdmPrimitiveTypeKind.Guid), - new SimpleEntry<>(Short.class,EdmPrimitiveTypeKind.Int16), - new SimpleEntry<>(Integer.class,EdmPrimitiveTypeKind.Int32), - new SimpleEntry<>(Long.class,EdmPrimitiveTypeKind.Int64), - new SimpleEntry<>(String.class,EdmPrimitiveTypeKind.String) - - ).collect(Collectors.toMap((e)-> e.getKey(),(e)-> e.getValue()))); - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java deleted file mode 100644 index 4cd979e931..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java +++ /dev/null @@ -1,269 +0,0 @@ -package org.baeldung.examples.olingo4.edm; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import javax.persistence.EntityManagerFactory; -import javax.persistence.metamodel.Attribute.PersistentAttributeType; -import javax.persistence.metamodel.EntityType; -import javax.persistence.metamodel.Metamodel; -import javax.persistence.metamodel.PluralAttribute; -import javax.persistence.metamodel.SingularAttribute; - -import org.apache.olingo.commons.api.edm.FullQualifiedName; -import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider; -import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer; -import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo; -import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet; -import org.apache.olingo.commons.api.edm.provider.CsdlEntityType; -import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty; -import org.apache.olingo.commons.api.edm.provider.CsdlProperty; -import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef; -import org.apache.olingo.commons.api.edm.provider.CsdlSchema; -import org.apache.olingo.commons.api.ex.ODataException; -import org.springframework.stereotype.Component; - -@Component -public class JpaEdmProvider extends CsdlAbstractEdmProvider { - - EntityManagerFactory emf; - - // - private EdmTypeMapper typeMapper; - - // Service Namespace - public static final String NAMESPACE = "Baeldung.OData"; - - // EDM Container - public static final String CONTAINER_NAME = "Cars"; - public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME); - - // Caches of OData types by it fully qualified name - private Map cdslName2Type = new HashMap<>(); - - public JpaEdmProvider(EntityManagerFactory emf, EdmTypeMapper mapper) { - this.emf = emf; - this.typeMapper = mapper; - } - - /* (non-Javadoc) - * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntitySet(org.apache.olingo.commons.api.edm.FullQualifiedName, java.lang.String) - */ - @Override - public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException { - - if (entityContainer.equals(CONTAINER)) { - - EntityType e = emf.getMetamodel() - .getEntities() - .stream() - .filter((ent) -> (ent.getName() + "s") - .equals(entitySetName)) - .findFirst() - .orElse(null); - - if (e != null) { - CsdlEntitySet entitySet = new CsdlEntitySet(); - entitySet - .setName(entitySetName) - .setType(new FullQualifiedName(NAMESPACE, e.getName())); - return entitySet; - } - } - - return null; - } - - /* (non-Javadoc) - * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntityContainerInfo(org.apache.olingo.commons.api.edm.FullQualifiedName) - */ - @Override - public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException { - - // This method is invoked when displaying the Service Document at e.g. http://localhost:8080/DemoService/DemoService.svc - if (entityContainerName == null || entityContainerName.equals(CONTAINER)) { - CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo(); - entityContainerInfo.setContainerName(CONTAINER); - return entityContainerInfo; - } - - return null; - } - - /* (non-Javadoc) - * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getSchemas() - */ - @Override - public List getSchemas() throws ODataException { - // create Schema - CsdlSchema schema = new CsdlSchema(); - schema.setNamespace(NAMESPACE); - - // add EntityTypes - List entityTypes = emf.getMetamodel() - .getEntities() - .stream() - .map((e) -> { - try { - return getEntityType(new FullQualifiedName(NAMESPACE, e.getName())); - } catch (ODataException oe) { - throw new RuntimeException(oe); - } - }) - .collect(Collectors.toList()); - - schema.setEntityTypes(entityTypes); - - // add EntityContainer - schema.setEntityContainer(getEntityContainer()); - - // finally - List schemas = new ArrayList(); - schemas.add(schema); - - return schemas; - } - - /* (non-Javadoc) - * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntityContainer() - */ - @Override - public CsdlEntityContainer getEntityContainer() throws ODataException { - - - // add EntityTypes - List entitySets = emf.getMetamodel() - .getEntities() - .stream() - .map((e) -> { - try { - // Here we use a simple mapping strategy to map entity types to entity set names: - return getEntitySet(CONTAINER, e.getName() + "s"); - } catch (ODataException oe) { - throw new RuntimeException(oe); - } - }) - .collect(Collectors.toList()); - - // create EntityContainer - CsdlEntityContainer entityContainer = new CsdlEntityContainer(); - entityContainer.setName(CONTAINER_NAME); - entityContainer.setEntitySets(entitySets); - - return entityContainer; - } - - @Override - public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException { - - CsdlEntityType result = cdslName2Type.get(entityTypeName); - if ( result != null ) { - return result; - } - - Metamodel mm = emf.getMetamodel(); - result = mm.getEntities() - .stream() - .filter(et -> entityTypeName.equals(new FullQualifiedName(NAMESPACE, et.getName()))) - .map(et -> buildODataType(et)) - .findFirst() - .orElse(null); - - // save for future use - cdslName2Type.put(entityTypeName, result); - return result; - - } - - /** - * Maps a JPA type to its OData counterpart. - * @param et - * @return - */ - protected CsdlEntityType buildODataType(EntityType et) { - - CsdlEntityType result = new CsdlEntityType(); - result.setName(et.getName()); - - // Process simple properties - List properties = et.getDeclaredSingularAttributes() - .stream() - .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC) - .map(attr -> buildBasicAttribute(et, attr)) - .collect(Collectors.toList()); - - result.setProperties(properties); - - // Process Ids - List ids = et.getDeclaredSingularAttributes() - .stream() - .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC && attr.isId()) - .map(attr -> buildRefAttribute(et, attr)) - .collect(Collectors.toList()); - - result.setKey(ids); - - // Process 1:N navs - List navs = et.getDeclaredPluralAttributes() - .stream() - .map(attr -> buildNavAttribute(et, attr)) - .collect(Collectors.toList()); - result.setNavigationProperties(navs); - - // Process N:1 navs - List navs2 = et.getDeclaredSingularAttributes() - .stream() - .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.MANY_TO_ONE) - .map(attr -> buildNavAttribute(et, attr)) - .collect(Collectors.toList()); - - result.getNavigationProperties().addAll(navs2); - - - return result; - } - - private CsdlProperty buildBasicAttribute(EntityType et, SingularAttribute attr) { - - CsdlProperty p = new CsdlProperty().setName(attr.getName()) - .setType(typeMapper.java2edm(attr.getJavaType()) - .getFullQualifiedName()) - .setNullable(et.getDeclaredSingularAttribute(attr.getName()) - .isOptional()); - - return p; - } - - private CsdlPropertyRef buildRefAttribute(EntityType et, SingularAttribute attr) { - - CsdlPropertyRef p = new CsdlPropertyRef().setName(attr.getName()); - - return p; - } - - // Build NavProperty for 1:N or M:N associations - private CsdlNavigationProperty buildNavAttribute(EntityType et, PluralAttribute attr) { - - CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName()) - .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) - .setCollection(true) - .setNullable(false); - - return p; - } - - // Build NavProperty for N:1 associations - private CsdlNavigationProperty buildNavAttribute(EntityType et, SingularAttribute attr) { - - CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName()) - .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) - .setCollection(false) - .setNullable(attr.isOptional()); - - return p; - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java deleted file mode 100644 index 4a4e5026f3..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.baeldung.examples.olingo4.processor; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Collection; -import java.util.List; - -import javax.persistence.EntityManagerFactory; -import javax.persistence.metamodel.EntityType; -import javax.persistence.metamodel.SingularAttribute; - -import org.apache.commons.beanutils.PropertyUtils; -import org.apache.olingo.commons.api.data.ContextURL; -import org.apache.olingo.commons.api.data.Entity; -import org.apache.olingo.commons.api.data.EntityCollection; -import org.apache.olingo.commons.api.data.Property; -import org.apache.olingo.commons.api.data.ValueType; -import org.apache.olingo.commons.api.edm.EdmEntitySet; -import org.apache.olingo.commons.api.edm.EdmEntityType; -import org.apache.olingo.commons.api.edm.EdmNavigationProperty; -import org.apache.olingo.commons.api.ex.ODataRuntimeException; -import org.apache.olingo.commons.api.format.ContentType; -import org.apache.olingo.commons.api.http.HttpHeader; -import org.apache.olingo.commons.api.http.HttpStatusCode; -import org.apache.olingo.server.api.OData; -import org.apache.olingo.server.api.ODataApplicationException; -import org.apache.olingo.server.api.ODataLibraryException; -import org.apache.olingo.server.api.ODataRequest; -import org.apache.olingo.server.api.ODataResponse; -import org.apache.olingo.server.api.ServiceMetadata; -import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor; -import org.apache.olingo.server.api.processor.EntityCollectionProcessor; -import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; -import org.apache.olingo.server.api.serializer.ODataSerializer; -import org.apache.olingo.server.api.serializer.SerializerResult; -import org.apache.olingo.server.api.uri.UriInfo; -import org.apache.olingo.server.api.uri.UriParameter; -import org.apache.olingo.server.api.uri.UriResource; -import org.apache.olingo.server.api.uri.UriResourceEntitySet; -import org.baeldung.examples.olingo4.repository.RepositoryRegistry; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Component; - -@Component -public class JpaEntityCollectionProcessor implements CountEntityCollectionProcessor { - - private OData odata; - private ServiceMetadata serviceMetadata; - private EntityManagerFactory emf; - private RepositoryRegistry repositoryRegistry; - private JpaEntityMapper entityMapper; - - public JpaEntityCollectionProcessor(EntityManagerFactory emf, RepositoryRegistry repositoryRegistry, JpaEntityMapper entityMapper) { - this.emf = emf; - this.repositoryRegistry = repositoryRegistry; - this.entityMapper = entityMapper; - } - - @Override - public void init(OData odata, ServiceMetadata serviceMetadata) { - this.odata = odata; - this.serviceMetadata = serviceMetadata; - } - - @Override - public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - - // 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI) - List resourcePaths = uriInfo.getUriResourceParts(); - UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet - EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); - - // 2nd: fetch the data from backend for this requested EntitySetName - // it has to be delivered as EntitySet object - EntityCollection entitySet = getData(edmEntitySet, uriInfo); - - // 3rd: create a serializer based on the requested format (json) - ODataSerializer serializer = odata.createSerializer(responseFormat); - - // 4th: Now serialize the content: transform from the EntitySet object to InputStream - EdmEntityType edmEntityType = edmEntitySet.getEntityType(); - ContextURL contextUrl = ContextURL.with() - .entitySet(edmEntitySet) - .build(); - - final String id = request.getRawBaseUri() + "/" + edmEntitySet.getName(); - EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with() - .id(id) - .contextURL(contextUrl) - .build(); - SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, entitySet, opts); - InputStream serializedContent = serializerResult.getContent(); - - // Finally: configure the response object: set the body, headers and status code - response.setContent(serializedContent); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); - - } - - @Override - public void countEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException { - - // 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI) - List resourcePaths = uriInfo.getUriResourceParts(); - UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet - EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); - - // 2nd: fetch the data from backend for this requested EntitySetName - Long count = getCount(edmEntitySet, uriInfo); - - // Finally: configure the response object: set the body, headers and status code - response.setContent(new ByteArrayInputStream(count.toString().getBytes())); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, "text/plain"); - - } - - /** - * Helper method to retrieve all entities of an entity set from an the backend database - * @param edmEntitySet - * @param uriInfo - * @return - */ - protected EntityCollection getData(EdmEntitySet edmEntitySet, UriInfo uriInfo) { - - EdmEntityType type = edmEntitySet.getEntityType(); - JpaRepository repo = (JpaRepository)repositoryRegistry.getRepositoryForEntity(type); - EntityCollection result = new EntityCollection(); - - repo.findAll() - .stream() - .forEach((it) -> result.getEntities() - .add(entityMapper.map2entity(edmEntitySet, it))); - - return result; - } - - - /** - * Helper method to get the total size of an entity set - * @param edmEntitySet - * @param uriInfo - * @return - */ - protected Long getCount(EdmEntitySet edmEntitySet, UriInfo uriInfo) { - - EdmEntityType type = edmEntitySet.getEntityType(); - JpaRepository repo = (JpaRepository)repositoryRegistry.getRepositoryForEntity(type); - EntityCollection result = new EntityCollection(); - - return repo.count(); - } - - - - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java deleted file mode 100644 index 1978aa4fd6..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * - */ -package org.baeldung.examples.olingo4.processor; - -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.net.URISyntaxException; - -import javax.persistence.EntityManagerFactory; -import javax.persistence.metamodel.EntityType; - -import org.apache.commons.beanutils.PropertyUtils; -import org.apache.olingo.commons.api.data.Entity; -import org.apache.olingo.commons.api.data.Property; -import org.apache.olingo.commons.api.data.ValueType; -import org.apache.olingo.commons.api.edm.EdmEntitySet; -import org.apache.olingo.commons.api.ex.ODataRuntimeException; -import org.springframework.stereotype.Component; - -/** - *

Helper class that converts a JPA entity into an OData entity using - * available metadata from the JPA's EntityManagerFactory.

- * - * @author Philippe - * - */ -@Component -public class JpaEntityMapper { - - private EntityManagerFactory emf; - - public JpaEntityMapper(EntityManagerFactory emf) { - this.emf = emf; - } - - - public Entity map2entity(EdmEntitySet edmEntitySet, Object entry) { - - EntityType et = emf.getMetamodel() - .entity(entry.getClass()); - - - Entity e = new Entity(); - try { - et.getDeclaredSingularAttributes().stream() - .forEach( (attr) -> { - if ( !attr.isAssociation()) { - Object v = getPropertyValue(entry,attr.getName()); - Property p = new Property(null, attr.getName(),ValueType.PRIMITIVE,v); - e.addProperty(p); - - if ( attr.isId()) { - e.setId(createId(edmEntitySet.getName(),v)); - } - } - }); - } catch (Exception ex) { - throw new ODataRuntimeException("[E141] Unable to create OData entity", ex); - } - - return e; - } - - - public Object getPropertyValue(Object entry, String name) { - try { - return PropertyUtils.getProperty(entry,name); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e); - } - } - - public void setPropertyValue(Object entry, String name,Object value) { - try { - PropertyUtils.setProperty(entry,name,value); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e); - } - } - - - private URI createId(String entitySetName, Object id) { - try { - return new URI(entitySetName + "(" + String.valueOf(id) + ")"); - } catch (URISyntaxException e) { - throw new ODataRuntimeException("[E177] Unable to create URI", e); - } - } - - - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java deleted file mode 100644 index 719e5de160..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java +++ /dev/null @@ -1,304 +0,0 @@ -/** - * - */ -package org.baeldung.examples.olingo4.processor; - -import java.io.InputStream; -import java.util.List; -import java.util.Locale; -import java.util.Optional; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.metamodel.SingularAttribute; - -import org.apache.olingo.commons.api.data.ContextURL; -import org.apache.olingo.commons.api.data.Entity; -import org.apache.olingo.commons.api.edm.EdmEntitySet; -import org.apache.olingo.commons.api.edm.EdmEntityType; -import org.apache.olingo.commons.api.edm.EdmNavigationProperty; -import org.apache.olingo.commons.api.ex.ODataRuntimeException; -import org.apache.olingo.commons.api.format.ContentType; -import org.apache.olingo.commons.api.http.HttpHeader; -import org.apache.olingo.commons.api.http.HttpStatusCode; -import org.apache.olingo.server.api.OData; -import org.apache.olingo.server.api.ODataApplicationException; -import org.apache.olingo.server.api.ODataLibraryException; -import org.apache.olingo.server.api.ODataRequest; -import org.apache.olingo.server.api.ODataResponse; -import org.apache.olingo.server.api.ServiceMetadata; -import org.apache.olingo.server.api.processor.EntityProcessor; -import org.apache.olingo.server.api.serializer.EntitySerializerOptions; -import org.apache.olingo.server.api.serializer.ODataSerializer; -import org.apache.olingo.server.api.serializer.SerializerResult; -import org.apache.olingo.server.api.uri.UriInfo; -import org.apache.olingo.server.api.uri.UriParameter; -import org.apache.olingo.server.api.uri.UriResource; -import org.apache.olingo.server.api.uri.UriResourceEntitySet; -import org.apache.olingo.server.api.uri.UriResourceNavigation; -import org.baeldung.examples.olingo4.repository.EdmEntityRepository; -import org.baeldung.examples.olingo4.repository.RepositoryRegistry; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Component; - -/** - * JpaEntityProcessor adapter. - *

This implementation is heavily based on the Tutorial available - * at Olingo's site. It is meant to be an starting point for an actual implementation.

- *

Please note that many features from a full-fledged are missing - * @author Philippe - * - */ -@Component -public class JpaEntityProcessor implements EntityProcessor { - - private EntityManagerFactory emf; - private OData odata; - private ServiceMetadata serviceMetadata; - private RepositoryRegistry registry; - private JpaEntityMapper entityMapper; - - public JpaEntityProcessor(EntityManagerFactory emf, RepositoryRegistry registry, JpaEntityMapper entityMapper) { - this.emf = emf; - this.registry = registry; - this.entityMapper = entityMapper; - } - - /* (non-Javadoc) - * @see org.apache.olingo.server.api.processor.Processor#init(org.apache.olingo.server.api.OData, org.apache.olingo.server.api.ServiceMetadata) - */ - @Override - public void init(OData odata, ServiceMetadata serviceMetadata) { - this.odata = odata; - this.serviceMetadata = serviceMetadata; - - } - - /* (non-Javadoc) - * @see org.apache.olingo.server.api.processor.EntityProcessor#readEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType) - */ - @Override - public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - - // First, we have to figure out which entity is requested - List resourceParts = uriInfo.getUriResourceParts(); - InputStream entityStream; - - UriResourceEntitySet rootResourceEntitySet = (UriResourceEntitySet) resourceParts.get(0); - EdmEntitySet rootEntitySet = rootResourceEntitySet.getEntitySet(); - List rootPredicates = rootResourceEntitySet.getKeyPredicates(); - - if ( resourceParts.size() == 1 ) { - entityStream = readRootEntity(rootEntitySet,rootPredicates,responseFormat); - } - else if ( resourceParts.size() == 2 ) { - UriResource part = resourceParts.get(1); - if ( !(part instanceof UriResourceNavigation)) { - throw new ODataRuntimeException("[E103] part type not supported: class=" + part.getClass().getName()); - } - - UriResourceNavigation navSegment = (UriResourceNavigation)part; - entityStream = readRelatedEntity(request, rootEntitySet,rootPredicates,navSegment.getProperty(),navSegment.getKeyPredicates(),responseFormat); - } - else { - // For now, we'll only allow navigation just to directly linked navs - throw new ODataApplicationException("[E109] Multi-level navigation not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); - } - - //4. configure the response object - response.setContent(entityStream); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); - - } - - - // Lookup the EntitySet associated with an EntityType - // In our example, we assume we have only one entityset for each entity type - private EdmEntitySet entitySetFromType(EdmEntityType type) { - return serviceMetadata - .getEdm() - .getEntityContainer() - .getEntitySets() - .stream() - .filter((s) -> s.getEntityType().getName().equals(type.getName())) - .findFirst() - .orElseThrow(() -> new ODataRuntimeException("[E144] No entity set found for type " + type.getFullQualifiedName())); - } - - // - // private boolean isOne2ManyProperty(EdmEntityType entityType, EdmNavigationProperty property) { - // return entityType.getProperty(property.getName()) != null && property.isCollection(); - //} - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private InputStream readRootEntity(EdmEntitySet entitySet, List keyPredicates,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - EdmEntityType type = entitySet.getEntityType(); - JpaRepository repo = registry.getRepositoryForEntity(type); - - // Get key value - Long keyValue = getEntityKey(keyPredicates); - Optional entry = repo.findById(keyValue); - if ( !entry.isPresent()) { - throw new ODataApplicationException( - "[E116] NO entity found for the given key", - HttpStatusCode.NOT_FOUND.getStatusCode(), - Locale.ENGLISH); - } - - Entity e = entityMapper.map2entity(entitySet, entry.get()); - return serializeEntity(entitySet,e,responseFormat); - } - - private InputStream serializeEntity(EdmEntitySet entitySet, Entity entity,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - ContextURL contextUrl = ContextURL.with().entitySet(entitySet).build(); - // expand and select currently not supported - EntitySerializerOptions options = EntitySerializerOptions - .with() - .contextURL(contextUrl) - .build(); - - ODataSerializer serializer = odata.createSerializer(responseFormat); - - SerializerResult serializerResult = serializer.entity(serviceMetadata, entitySet.getEntityType(), entity, options); - return serializerResult.getContent(); - - } - -// @SuppressWarnings("unchecked") -// protected InputStream readRelatedEntities(EdmEntitySet rootEntitySet, List rootPredicates, EdmNavigationProperty property, ContentType responseFormat) throws ODataApplicationException { -// -// Object jpaEntity = readJPAEntity(rootEntitySet, rootPredicates); -// try { -// Collection set = (Collection)PropertyUtils.getProperty(jpaEntity, property.getName()); -// EdmEntitySet entitySet = entitySetFromType(property.getType()); -// ContextURL contextUrl = ContextURL -// .with() -// .entitySet(entitySet) -// .build(); -// -// EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions -// .with() -// .contextURL(contextUrl) -// .build(); -// -// EntityCollection result = new EntityCollection(); -// -// set.stream() -// .map((o) -> this.entityMapper.map2entity(entitySet, o)) -// .forEach((e) -> result.getEntities().add(e)); -// -// ODataSerializer serializer = odata.createSerializer(responseFormat); -// SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, property.getType(), result, options); -// return serializerResult.getContent(); -// } -// catch(Exception ex) { -// throw new ODataRuntimeException("[E181] Error accessing database", ex); -// } -// } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private InputStream readRelatedEntity(ODataRequest request, EdmEntitySet entitySet, List rootPredicates, EdmNavigationProperty property, List parentPredicates, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - - - JpaRepository repo = (JpaRepository)registry.getRepositoryForEntity(entitySet.getEntityType()); - EdmEntityRepository relatedRepo = (EdmEntityRepository)registry.getRepositoryForEntity(property.getType()); - - // We assume here that we have a bi-directional 1:N relationship, so we'll - // always have a property in the child entity that points to the parent - Class rootClass = ((EdmEntityRepository)repo).getEntityClass(); - Class relatedClass = ((EdmEntityRepository)relatedRepo).getEntityClass(); - - SingularAttribute fk = emf.getMetamodel() - .entity(rootClass) - .getSingularAttributes() - .stream() - .filter((attr) -> { - boolean b = attr.isAssociation() && attr.getJavaType().isAssignableFrom(relatedClass); - return b; - }) - .findFirst() - .orElse(null); - - if ( fk == null ) { - throw new ODataRuntimeException("[E230] No singular attribute of child class '" + relatedClass.getName() + "' found" ); - } - - Long pkValue = getEntityKey(rootPredicates); - EntityManager em = this.emf.createEntityManager(); - try { - // Read data from DB - Object root = em.find(rootClass, pkValue); - Object related = this.entityMapper.getPropertyValue(root, fk.getName()); - - EdmEntitySet relatedEntitySet = entitySetFromType(property.getType()); - Entity e = entityMapper.map2entity(relatedEntitySet, related); - return serializeEntity(relatedEntitySet,e,responseFormat); - } - finally { - em.close(); - } - } - -// @SuppressWarnings("unchecked") -// private Object readJPAEntity(EdmEntitySet edmEntitySet, List keyPredicates) throws ODataApplicationException { -// EdmEntityType type = edmEntitySet.getEntityType(); -// JpaRepository repo = (JpaRepository)registry.getRepositoryForEntity(type); -// -// // Get key value -// Object keyValue = getEntityKey(type,keyPredicates); -// Object entry = repo -// .findById(keyValue) -// .orElseThrow( -// () -> new ODataApplicationException("[E116] NO entity found for the given key", -// HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH)); -// -// return entry; -// } - - private Long getEntityKey(List keyPredicates) { - - if ( keyPredicates.size() > 1 ) { - throw new ODataRuntimeException("[E131] Composite keys are not supported"); - } - - // For now, we'll assume we only have numeric keys. - UriParameter keyParam = keyPredicates.get(0); - try { - return Long.parseLong(keyParam.getText()); - } - catch(NumberFormatException nfe) { - throw new ODataRuntimeException("[E140] Invalid key value. Only numeric keys are supported by this service"); - } - - - } - - /* (non-Javadoc) - * @see org.apache.olingo.server.api.processor.EntityProcessor#createEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType, org.apache.olingo.commons.api.format.ContentType) - */ - @Override - public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - // TODO Auto-generated method stub - - } - - /* (non-Javadoc) - * @see org.apache.olingo.server.api.processor.EntityProcessor#updateEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType, org.apache.olingo.commons.api.format.ContentType) - */ - @Override - public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - // TODO Auto-generated method stub - - } - - /* (non-Javadoc) - * @see org.apache.olingo.server.api.processor.EntityProcessor#deleteEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo) - */ - @Override - public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException { - // TODO Auto-generated method stub - - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java deleted file mode 100644 index 1bde9f148c..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.examples.olingo4.repository; - -import org.baeldung.examples.olingo4.domain.CarMaker; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.stereotype.Repository; - -@Repository -public interface CarMakerRepository extends EdmEntityRepository, JpaRepository, JpaSpecificationExecutor { - - public default String getEdmEntityName() { return CarMaker.class.getSimpleName();} - @Override - default Class getEntityClass() { - return CarMaker.class; - } -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java deleted file mode 100644 index 247bf6e77b..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.baeldung.examples.olingo4.repository; - -import java.util.List; - -import org.baeldung.examples.olingo4.domain.CarModel; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.stereotype.Repository; - -@Repository -public interface CarModelRepository extends EdmEntityRepository, JpaRepository, JpaSpecificationExecutor { - - public List findByMakerId(Long makerId); - - public default String getEdmEntityName() { return CarModel.class.getSimpleName();} - - @Override - default Class getEntityClass() { - return CarModel.class; - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java deleted file mode 100644 index dbfd0e6f93..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -/** - * - */ -package org.baeldung.examples.olingo4.repository; - - -/** - * @author Philippe - * - */ -public interface EdmEntityRepository { - - public String getEdmEntityName(); - public Class getEntityClass(); - - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java deleted file mode 100644 index e3bb172e3a..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.baeldung.examples.olingo4.repository; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.olingo.commons.api.edm.EdmEntityType; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Component; - -@Component -public class RepositoryRegistry { - - private Map> repositoriesByClassName = new HashMap<>(); - - public RepositoryRegistry(List> allRepositories) { - - allRepositories.stream() - .forEach((r) -> - repositoriesByClassName.put(r.getEdmEntityName(),(JpaRepository)r)); - - } - - - public JpaRepository getRepositoryForEntity(EdmEntityType entityType) { - JpaRepository repo = repositoriesByClassName.get(entityType.getName()); - return repo; - } -} diff --git a/apache-olingo/olingo4/src/main/resources/application.properties b/apache-olingo/olingo4/src/main/resources/application.properties deleted file mode 100644 index 02c7fe5c4d..0000000000 --- a/apache-olingo/olingo4/src/main/resources/application.properties +++ /dev/null @@ -1,9 +0,0 @@ -server: - port: 8080 - -spring: - jpa: - show-sql: true - open-in-view: true - hibernate: - ddl-auto: update diff --git a/apache-olingo/olingo4/src/main/resources/data.sql b/apache-olingo/olingo4/src/main/resources/data.sql deleted file mode 100644 index 327f2688c5..0000000000 --- a/apache-olingo/olingo4/src/main/resources/data.sql +++ /dev/null @@ -1,12 +0,0 @@ -insert into car_maker(id,name) values (1,'Special Motors'); -insert into car_maker(id,name) values (2,'BWM'); -insert into car_maker(id,name) values (3,'Dolores'); - -insert into car_model(id,maker_fk,name,sku,year) values(1,1,'Muze','SM001',2018); -insert into car_model(id,maker_fk,name,sku,year) values(2,1,'Empada','SM002',2008); - -insert into car_model(id,maker_fk,name,sku,year) values(4,2,'BWM-100','BWM100',2008); -insert into car_model(id,maker_fk,name,sku,year) values(5,2,'BWM-200','BWM200',2009); -insert into car_model(id,maker_fk,name,sku,year) values(6,2,'BWM-300','BWM300',2008); - -alter sequence hibernate_sequence restart with 100; \ No newline at end of file diff --git a/apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java b/apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java deleted file mode 100644 index 5d23a4148e..0000000000 --- a/apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.examples.olingo4; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class Olingo4SampleApplicationTests { - - @Test - public void contextLoads() { - } - -} diff --git a/clojure/ring/.gitignore b/clojure/ring/.gitignore new file mode 100644 index 0000000000..d18f225992 --- /dev/null +++ b/clojure/ring/.gitignore @@ -0,0 +1,12 @@ +/target +/classes +/checkouts +profiles.clj +pom.xml +pom.xml.asc +*.jar +*.class +/.lein-* +/.nrepl-port +.hgignore +.hg/ diff --git a/clojure/ring/README.md b/clojure/ring/README.md new file mode 100644 index 0000000000..20263c6b95 --- /dev/null +++ b/clojure/ring/README.md @@ -0,0 +1,19 @@ +# Clojure Ring Examples + +This project acts as a set of examples for the Clojure Ring library. + +## Runing the examples + +The examples can all be run from the Leiningen REPL. + +Firstly, start the REPL with `lein repl`. Then the examples can be executed with: + +* `(run simple-handler)` - A simple handler that just echos a constant string to the client +* `(run check-ip-handler)` - A handler that echos the clients IP Address back to them +* `(run echo-handler)` - A handler that echos the value of the "input" parameter back +* `(run request-count-handler)` - A handler with a session that tracks how many times this session has requested this handler + +In all cases, the handlers can be accessed on http://localhost:3000. + +## Relevant Articles +- [Writing Clojure Webapps with Ring](https://www.baeldung.com/clojure-ring) diff --git a/clojure/ring/project.clj b/clojure/ring/project.clj new file mode 100644 index 0000000000..7f2fcc4263 --- /dev/null +++ b/clojure/ring/project.clj @@ -0,0 +1,8 @@ +(defproject baeldung-ring "0.1.0-SNAPSHOT" + :dependencies [[org.clojure/clojure "1.10.0"] + [ring/ring-core "1.7.1"] + [ring/ring-jetty-adapter "1.7.1"] + [ring/ring-devel "1.7.1"]] + :plugins [[lein-ring "0.12.5"]] + :ring {:handler ring.core/simple-handler} + :repl-options {:init-ns ring.core}) diff --git a/clojure/ring/src/ring/core.clj b/clojure/ring/src/ring/core.clj new file mode 100644 index 0000000000..a56e2f2bde --- /dev/null +++ b/clojure/ring/src/ring/core.clj @@ -0,0 +1,48 @@ +(ns ring.core + (:use ring.adapter.jetty + [ring.middleware.content-type] + [ring.middleware.cookies] + [ring.middleware.params] + [ring.middleware.session] + [ring.middleware.session.cookie] + [ring.util.response])) + +;; Handler that just echos back the string "Hello World" +(defn simple-handler [request] + {:status 200 + :headers {"Content-Type" "text/plain"} + :body "Hello World"}) + +;; Handler that echos back the clients IP Address +;; This demonstrates building responses properly, and extracting values from the request +(defn check-ip-handler [request] + (content-type + (response (:remote-addr request)) + "text/plain")) + +;; Handler that echos back the incoming parameter "input" +;; This demonstrates middleware chaining and accessing parameters +(def echo-handler + (-> (fn [{params :params}] + (content-type + (response (get params "input")) + "text/plain")) + (wrap-params {:encoding "UTF-8"}) + )) + +;; Handler that keeps track of how many times each session has accessed the service +;; This demonstrates cookies and sessions +(def request-count-handler + (-> (fn [{session :session}] + (let [count (:count session 0) + session (assoc session :count (inc count))] + (-> (response (str "You accessed this page " count " times.")) + (assoc :session session)))) + wrap-cookies + (wrap-session {:cookie-attrs {:max-age 3600}}) + )) + +;; Run the provided handler on port 3000 +(defn run + [h] + (run-jetty h {:port 3000})) diff --git a/core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java b/core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java new file mode 100644 index 0000000000..58cbe22df5 --- /dev/null +++ b/core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java @@ -0,0 +1,15 @@ +package com.baeldung.error; + +public class ErrorGenerator { + public void throwException() throws Exception { + throw new Exception("checked"); + } + + public void throwRuntimeException() { + throw new RuntimeException("unchecked"); + } + + public void throwError() { + throw new Error("unchecked"); + } +} diff --git a/core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java b/core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java new file mode 100644 index 0000000000..2a7c24f5fa --- /dev/null +++ b/core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.error; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ErrorGeneratorUnitTest { + + private ErrorGenerator errorGenerator; + + @Before + public void setUp() { + errorGenerator = new ErrorGenerator(); + } + + @Test + public void whenCheckedException_thenIsCaughtByCatchException() { + try { + errorGenerator.throwException(); + } catch (Exception e) { + // caught! -> test pass + } + } + + @Test + public void whenUncheckedException_thenIsCaughtByCatchException() { + try { + errorGenerator.throwRuntimeException(); + } catch (Exception e) { + // caught! -> test pass + } + } + + @Test(expected = Error.class) + public void whenError_thenIsNotCaughtByCatchException() { + try { + errorGenerator.throwError(); + } catch (Exception e) { + Assert.fail(); // errors are not caught by catch exception + } + } + + @Test + public void whenError_thenIsCaughtByCatchError() { + try { + errorGenerator.throwError(); + } catch (Error e) { + // caught! -> test pass + } + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-11/pom.xml b/core-java-modules/core-java-11/pom.xml index b78c141552..4d950bdf8d 100644 --- a/core-java-modules/core-java-11/pom.xml +++ b/core-java-modules/core-java-11/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 com.baeldung core-java-11 @@ -12,7 +14,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../../ + ../.. @@ -21,6 +23,12 @@ guava ${guava.version} + + org.assertj + assertj-core + ${assertj.version} + test + @@ -41,6 +49,7 @@ 11 11 27.1-jre + 3.11.1 diff --git a/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/Person.java b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/Person.java new file mode 100644 index 0000000000..3c93e08194 --- /dev/null +++ b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/Person.java @@ -0,0 +1,19 @@ +package com.baeldung.predicate.not; + +public class Person { + private static final int ADULT_AGE = 18; + + private int age; + + public Person(int age) { + this.age = age; + } + + public boolean isAdult() { + return age >= ADULT_AGE; + } + + public boolean isNotAdult() { + return !isAdult(); + } +} diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/AppTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/AppUnitTest.java similarity index 82% rename from core-java-modules/core-java-11/src/test/java/com/baeldung/AppTest.java rename to core-java-modules/core-java-11/src/test/java/com/baeldung/AppUnitTest.java index c9f61455bd..73eb8e661a 100644 --- a/core-java-modules/core-java-11/src/test/java/com/baeldung/AppTest.java +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/AppUnitTest.java @@ -7,7 +7,7 @@ import junit.framework.TestSuite; /** * Unit test for simple App. */ -public class AppTest +public class AppUnitTest extends TestCase { /** @@ -15,7 +15,7 @@ public class AppTest * * @param testName name of the test case */ - public AppTest( String testName ) + public AppUnitTest(String testName ) { super( testName ); } @@ -25,7 +25,7 @@ public class AppTest */ public static Test suite() { - return new TestSuite( AppTest.class ); + return new TestSuite( AppUnitTest.class ); } /** diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientUnitTest.java similarity index 99% rename from core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientTest.java rename to core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientUnitTest.java index 0e9c12675c..42f56838c4 100644 --- a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientTest.java +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientUnitTest.java @@ -32,7 +32,7 @@ import java.util.stream.Collectors; import org.junit.jupiter.api.Test; -public class HttpClientTest { +public class HttpClientUnitTest { @Test public void shouldReturnSampleDataContentWhenConnectViaSystemProxy() throws IOException, InterruptedException, URISyntaxException { diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestUnitTest.java similarity index 99% rename from core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestTest.java rename to core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestUnitTest.java index 274d3a93fc..b87e6b3c6e 100644 --- a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestTest.java +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestUnitTest.java @@ -19,7 +19,7 @@ import java.time.Duration; import org.junit.Test; -public class HttpRequestTest { +public class HttpRequestUnitTest { @Test public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException { diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseUnitTest.java similarity index 98% rename from core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseTest.java rename to core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseUnitTest.java index abbc0233c1..a5cfc3f6b1 100644 --- a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseTest.java +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseUnitTest.java @@ -14,7 +14,7 @@ import java.net.http.HttpResponse; import org.junit.Test; -public class HttpResponseTest { +public class HttpResponseUnitTest { @Test public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException { diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/predicate/not/PersonUnitTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/predicate/not/PersonUnitTest.java new file mode 100644 index 0000000000..a4989287be --- /dev/null +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/predicate/not/PersonUnitTest.java @@ -0,0 +1,61 @@ +package com.baeldung.predicate.not; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.function.Predicate.not; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class PersonUnitTest { + private List people; + + @BeforeEach + void preparePeople() { + people = Arrays.asList( + new Person(1), + new Person(18), + new Person(2) + ); + } + + @Test + void givenPeople_whenFilterIsAdult_thenOneResult() { + List adults = people.stream() + .filter(Person::isAdult) + .collect(Collectors.toList()); + + assertThat(adults).size().isEqualTo(1); + } + + @Test + void givenPeople_whenFilterIsAdultNegated_thenTwoResults() { + List nonAdults = people.stream() + .filter(person -> !person.isAdult()) + .collect(Collectors.toList()); + + assertThat(nonAdults).size().isEqualTo(2); + } + + @Test + void givenPeople_whenFilterIsNotAdult_thenTwoResults() { + List nonAdults = people.stream() + .filter(Person::isNotAdult) + .collect(Collectors.toList()); + + assertThat(nonAdults).size().isEqualTo(2); + } + + @Test + void givenPeople_whenFilterNotIsAdult_thenTwoResults() { + List nonAdults = people.stream() + .filter(not(Person::isAdult)) + .collect(Collectors.toList()); + + assertThat(nonAdults).size().isEqualTo(2); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/delay/Delay.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/delay/Delay.java new file mode 100644 index 0000000000..0cc0c9487f --- /dev/null +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/delay/Delay.java @@ -0,0 +1,91 @@ +package com.baeldung.delay; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +public class Delay { + + public static void main(String args[]) throws InterruptedException { + + threadSleep(4, 1); + + timeunitSleep(4, 1); + + delayedServiceTask(5); + + fixedRateServiceTask(5); + + System.out.println("Done."); + + return; + + } + + private static void threadSleep(Integer iterations, Integer secondsToSleep) { + + for (Integer i = 0; i < iterations; i++) { + + System.out.println("This is loop iteration number " + i.toString()); + + try { + Thread.sleep(secondsToSleep * 1000); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + + } + + } + + private static void timeunitSleep(Integer iterations, Integer secondsToSleep) { + + for (Integer i = 0; i < iterations; i++) { + + System.out.println("This is loop iteration number " + i.toString()); + + try { + TimeUnit.SECONDS.sleep(secondsToSleep); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + + } + + } + + private static void delayedServiceTask(Integer delayInSeconds) { + + ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + + executorService.schedule(Delay::someTask1, delayInSeconds, TimeUnit.SECONDS); + + } + + private static void fixedRateServiceTask(Integer delayInSeconds) { + + ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + + ScheduledFuture sf = executorService.scheduleAtFixedRate(Delay::someTask2, 0, delayInSeconds, + TimeUnit.SECONDS); + + try { + TimeUnit.SECONDS.sleep(20); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + + sf.cancel(true); + + } + + private static void someTask1() { + System.out.println("Task 1 completed."); + } + + private static void someTask2() { + System.out.println("Task 2 completed."); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java b/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java index df41e071fd..db19613c94 100644 --- a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java +++ b/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java @@ -4,6 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ResourceBundle; +import java.text.MessageFormat; public class Slf4jLogger implements System.Logger { @@ -74,26 +75,27 @@ public class Slf4jLogger implements System.Logger { if (!isLoggable(level)) { return; } + String message = MessageFormat.format(format, params); switch (level) { case TRACE: - logger.trace(format, params); + logger.trace(message); break; case DEBUG: - logger.debug(format, params); + logger.debug(message); break; case INFO: - logger.info(format, params); + logger.info(message); break; case WARNING: - logger.warn(format, params); + logger.warn(message); break; case ERROR: - logger.error(format, params); + logger.error(message); break; case ALL: default: - logger.info(format, params); + logger.info(message); } } } diff --git a/core-java-modules/core-java-collections-list/src/test/java/com/baeldung/java/list/WaysToIterateUnitTest.java b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/list/WaysToIterateUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-list/src/test/java/com/baeldung/java/list/WaysToIterateUnitTest.java rename to core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/list/WaysToIterateUnitTest.java diff --git a/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/numberformat/NumberFormatExceptionUnitTest.java b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/numberformat/NumberFormatExceptionUnitTest.java index a1e8c7c30f..cb26bf451a 100644 --- a/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/numberformat/NumberFormatExceptionUnitTest.java +++ b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/numberformat/NumberFormatExceptionUnitTest.java @@ -36,7 +36,7 @@ public class NumberFormatExceptionUnitTest { @Test(expected = NumberFormatException.class) public void givenParseIntMethod_whenUnderscoreInInput_thenFail() { - int bIntPrim = Integer.parseInt("6_000"); + int bIntPrim = Integer.parseInt("_6000"); } @Test(expected = NumberFormatException.class) @@ -51,7 +51,7 @@ public class NumberFormatExceptionUnitTest { @Test(expected = NumberFormatException.class) public void givenDecodeMethod_whenAlphabetInInput_thenFail() { - Long decodeInteger = Long.decode("64403L"); + Long decodedLong = Long.decode("64403L"); } /* ---INTEGER PASS CASES--- */ @@ -72,7 +72,7 @@ public class NumberFormatExceptionUnitTest { int aIntPrim = Integer.parseInt("6000 ".trim()); assertEquals(6000, aIntPrim); - int bIntPrim = Integer.parseInt("6_000".replaceAll("_", "")); + int bIntPrim = Integer.parseInt("_6000".replaceAll("_", "")); assertEquals(6000, bIntPrim); int cIntPrim = Integer.parseInt("-6000"); diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml new file mode 100644 index 0000000000..6a41ec0d1a --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + consumermodule + jar + 1.0 + + + com.baeldung.decoupling-pattern1 + decoupling-pattern1 + 1.0 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + + + com.baeldung.servicemodule + servicemodule + 1.0 + + + diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java new file mode 100644 index 0000000000..c4b5eed011 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java @@ -0,0 +1,13 @@ +package com.baeldung.consumermodule; + +import com.baeldung.servicemodule.external.TextService; +import com.baeldung.servicemodule.external.TextServiceFactory; + +public class Application { + + public static void main(String args[]) { + TextService textService = TextServiceFactory.getTextService("lowercase"); + System.out.println(textService.processText("Hello from Baeldung!")); + } + +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/module-info.java new file mode 100644 index 0000000000..c02e6e6522 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.consumermodule { + requires com.baeldung.servicemodule; +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern1/pom.xml new file mode 100644 index 0000000000..282723e0a0 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + com.baeldung.decoupling-pattern1 + decoupling-pattern1 + 1.0 + pom + + + servicemodule + consumermodule + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 11 + 11 + + + + + + + + UTF-8 + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/pom.xml new file mode 100644 index 0000000000..1bda70f867 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + com.baeldung.servicemodule + servicemodule + jar + + + com.baeldung.decoupling-pattern1 + decoupling-pattern1 + 1.0 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextService.java b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextService.java new file mode 100644 index 0000000000..2b9f0dce50 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextService.java @@ -0,0 +1,7 @@ +package com.baeldung.servicemodule.external; + +public interface TextService { + + String processText(String text); + +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java new file mode 100644 index 0000000000..4611bc1c8c --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java @@ -0,0 +1,14 @@ +package com.baeldung.servicemodule.external; + +import com.baeldung.servicemodule.internal.LowercaseTextService; +import com.baeldung.servicemodule.internal.UppercaseTextService; + +public class TextServiceFactory { + + private TextServiceFactory() {} + + public static TextService getTextService(String name) { + return name.equalsIgnoreCase("lowercase") ? new LowercaseTextService(): new UppercaseTextService(); + } + +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java new file mode 100644 index 0000000000..e2d98f609e --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java @@ -0,0 +1,12 @@ +package com.baeldung.servicemodule.internal; + +import com.baeldung.servicemodule.external.TextService; + +public class LowercaseTextService implements TextService { + + @Override + public String processText(String text) { + return text.toLowerCase(); + } + +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java new file mode 100644 index 0000000000..c94da2a8a5 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java @@ -0,0 +1,12 @@ +package com.baeldung.servicemodule.internal; + +import com.baeldung.servicemodule.external.TextService; + +public class UppercaseTextService implements TextService { + + @Override + public String processText(String text) { + return text.toUpperCase(); + } + +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/module-info.java new file mode 100644 index 0000000000..230b659aa9 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.servicemodule { + exports com.baeldung.servicemodule.external; +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml new file mode 100644 index 0000000000..828fe7de6a --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml @@ -0,0 +1,38 @@ + + + + com.baeldung.decoupling-pattern2 + decoupling-pattern2 + 1.0-SNAPSHOT + + 4.0.0 + + com.baeldung.consumermodule + consumermodule + 1.0 + + + + com.baeldung.servicemodule + servicemodule + 1.0 + + + com.baeldung.providermodule + providermodule + 1.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java new file mode 100644 index 0000000000..b9430eb458 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java @@ -0,0 +1,15 @@ +package com.baeldung.consumermodule; + +import com.baeldung.servicemodule.TextService; + +import java.util.ServiceLoader; + +public class Application { + + public static void main(String[] args) { + ServiceLoader services = ServiceLoader.load(TextService.class); + for (final TextService service: services) { + System.out.println("The service " + service.getClass().getSimpleName() + " says: " + service.parseText("Hello from Baeldung!")); + } + } +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/module-info.java new file mode 100644 index 0000000000..d8438a7bbc --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module com.baeldung.consumermodule { + requires com.baeldung.servicemodule; + uses com.baeldung.servicemodule.TextService; +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern2/pom.xml new file mode 100644 index 0000000000..f8c05d40b8 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + com.baeldung.decoupling-pattern2 + decoupling-pattern2 + 1.0-SNAPSHOT + pom + + + servicemodule + providermodule + consumermodule + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 11 + 11 + + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/pom.xml new file mode 100644 index 0000000000..ceeda9049c --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/pom.xml @@ -0,0 +1,34 @@ + + + + 4.0.0 + com.baeldung.providermodule + providermodule + 1.0 + + + com.baeldung.decoupling-pattern2 + decoupling-pattern2 + 1.0-SNAPSHOT + + + + + com.baeldung.servicemodule + servicemodule + 1.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java new file mode 100644 index 0000000000..51e742e641 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java @@ -0,0 +1,10 @@ +package com.baeldung.providermodule; + +import com.baeldung.servicemodule.TextService; + +public class LowercaseTextService implements TextService { + @Override + public String parseText(String text) { + return text.toLowerCase(); + } +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/module-info.java new file mode 100644 index 0000000000..1223aa0121 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module com.baeldung.providermodule { + requires com.baeldung.servicemodule; + provides com.baeldung.servicemodule.TextService with com.baeldung.providermodule.LowercaseTextService; +} \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/pom.xml new file mode 100644 index 0000000000..4de3df8c01 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + >com.baeldung.decoupling-pattern2 + decoupling-pattern2 + 1.0-SNAPSHOT + + + com.baeldung.servicemodule + servicemodule + 1.0 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/com/baeldung/servicemodule/TextService.java b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/com/baeldung/servicemodule/TextService.java new file mode 100644 index 0000000000..dedbd774ca --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/com/baeldung/servicemodule/TextService.java @@ -0,0 +1,6 @@ +package com.baeldung.servicemodule; + +public interface TextService { + + String parseText(String text); +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/module-info.java new file mode 100644 index 0000000000..dbd70b944b --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.servicemodule { + exports com.baeldung.servicemodule; +} \ No newline at end of file diff --git a/core-java-modules/core-java-lambdas/README.MD b/core-java-modules/core-java-lambdas/README.MD new file mode 100644 index 0000000000..31790ffbb1 --- /dev/null +++ b/core-java-modules/core-java-lambdas/README.MD @@ -0,0 +1,3 @@ +### Relevant Articles + +- [Why Do Local Variables Used in Lambdas Have to Be Final or Effectively Final?](https://www.baeldung.com/java-lambda-effectively-final-local-variables) diff --git a/core-java-modules/core-java-nio/.gitignore b/core-java-modules/core-java-nio/.gitignore new file mode 100644 index 0000000000..c61d35324d --- /dev/null +++ b/core-java-modules/core-java-nio/.gitignore @@ -0,0 +1,5 @@ +0.* + +# Files generated by integration tests +# *.txt +/temp \ No newline at end of file diff --git a/core-java-modules/core-java-nio/pom.xml b/core-java-modules/core-java-nio/pom.xml new file mode 100644 index 0000000000..36d6848998 --- /dev/null +++ b/core-java-modules/core-java-nio/pom.xml @@ -0,0 +1,16 @@ + + 4.0.0 + core-java-nio + 0.1.0-SNAPSHOT + core-java-nio + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + \ No newline at end of file diff --git a/core-java-modules/core-java-nio/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java new file mode 100644 index 0000000000..d661b8f7fb --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java @@ -0,0 +1,165 @@ +package com.baeldung.filechannel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.charset.StandardCharsets; + +import org.junit.Test; + +public class FileChannelUnitTest { + + @Test + public void givenFile_whenReadWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel(); + ByteArrayOutputStream out = new ByteArrayOutputStream()) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + + assertEquals("Hello world", fileContent); + } + } + + @Test + public void givenFile_whenReadWithFileChannelUsingFileInputStream_thenCorrect() throws IOException { + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + FileInputStream fin = new FileInputStream("src/test/resources/test_read.in"); + FileChannel channel = fin.getChannel()) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + + assertEquals("Hello world", fileContent); + } + } + + @Test + public void givenFile_whenReadAFileSectionIntoMemoryWithFileChannel_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel(); + ByteArrayOutputStream out = new ByteArrayOutputStream()) { + + MappedByteBuffer buff = channel.map(FileChannel.MapMode.READ_ONLY, 6, 5); + + if (buff.hasRemaining()) { + byte[] data = new byte[buff.remaining()]; + buff.get(data); + assertEquals("world", new String(data, StandardCharsets.UTF_8)); + } + } + } + + @Test + public void whenWriteWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException { + String file = "src/test/resources/test_write_using_filechannel.txt"; + try (RandomAccessFile writer = new RandomAccessFile(file, "rw"); + FileChannel channel = writer.getChannel()) { + ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8)); + + channel.write(buff); + + // now we verify whether the file was written correctly + RandomAccessFile reader = new RandomAccessFile(file, "r"); + assertEquals("Hello world", reader.readLine()); + reader.close(); + } + } + + @Test + public void givenFile_whenWriteAFileUsingLockAFileSectionWithFileChannel_thenCorrect() throws IOException { + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "rw"); + FileChannel channel = reader.getChannel(); + FileLock fileLock = channel.tryLock(6, 5, Boolean.FALSE);) { + + assertNotNull(fileLock); + } + } + + @Test + public void givenFile_whenReadWithFileChannelGetPosition_thenCorrect() throws IOException { + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel()) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + + // the original file is 11 bytes long, so that's where the position pointer should be + assertEquals(11, channel.position()); + + channel.position(4); + assertEquals(4, channel.position()); + } + } + + @Test + public void whenGetFileSize_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel()) { + + // the original file is 11 bytes long, so that's where the position pointer should be + assertEquals(11, channel.size()); + } + } + + @Test + public void whenTruncateFile_thenCorrect() throws IOException { + String input = "this is a test input"; + + FileOutputStream fout = new FileOutputStream("src/test/resources/test_truncate.txt"); + FileChannel channel = fout.getChannel(); + + ByteBuffer buff = ByteBuffer.wrap(input.getBytes()); + channel.write(buff); + buff.flip(); + + channel = channel.truncate(5); + assertEquals(5, channel.size()); + + fout.close(); + channel.close(); + } +} diff --git a/core-java-modules/core-java-nio/src/test/resources/.gitignore b/core-java-modules/core-java-nio/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/core-java-modules/core-java-nio/src/test/resources/test_read.in b/core-java-modules/core-java-nio/src/test/resources/test_read.in new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/resources/test_read.in @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/core-java-modules/core-java-nio/src/test/resources/test_truncate.txt b/core-java-modules/core-java-nio/src/test/resources/test_truncate.txt new file mode 100644 index 0000000000..26d3b38cdd --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/resources/test_truncate.txt @@ -0,0 +1 @@ +this \ No newline at end of file diff --git a/core-java-modules/core-java-nio/src/test/resources/test_write_using_filechannel.txt b/core-java-modules/core-java-nio/src/test/resources/test_write_using_filechannel.txt new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/resources/test_write_using_filechannel.txt @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt b/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt index 3f9922b88b..f66f8fbae0 100644 --- a/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt +++ b/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt @@ -5,6 +5,8 @@ import java.util.* interface Document { @JvmDefault + fun getTypeDefault() = "document" + fun getType() = "document" } @@ -23,9 +25,3 @@ class TextDocument : Document { } class XmlDocument(d : Document) : Document by d - -fun main() { - val myDocument = TextDocument() - val myTextDocument = XmlDocument(myDocument) - println("${myDocument.getType()} ${myTextDocument.getType()}") -} diff --git a/core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt b/core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt new file mode 100644 index 0000000000..449e009104 --- /dev/null +++ b/core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt @@ -0,0 +1,18 @@ +package com.baeldung.range + +import org.junit.Test +import kotlin.test.assertEquals + +class DocumentTest { + + @Test + fun testDefaultMethod() { + + val myDocument = TextDocument() + val myTextDocument = XmlDocument(myDocument) + + assertEquals("text", myDocument.getType()) + assertEquals("text", myTextDocument.getType()) + assertEquals("document", myTextDocument.getTypeDefault()) + } +} \ No newline at end of file diff --git a/java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearch.java b/java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearchUnitTest.java similarity index 98% rename from java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearch.java rename to java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearchUnitTest.java index 4a5adb45ef..293e6d2125 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearch.java +++ b/java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearchUnitTest.java @@ -10,7 +10,7 @@ import org.junit.Test; /** * BAEL-2832: Different ways to check if a Substring could be found in a String. */ -public class SubstringSearch { +public class SubstringSearchUnitTest { @Test public void searchSubstringWithIndexOf() { diff --git a/jersey/src/main/java/com/baeldung/jersey/server/ItemParam.java b/jersey/src/main/java/com/baeldung/jersey/server/ItemParam.java new file mode 100644 index 0000000000..0f60a20b92 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/ItemParam.java @@ -0,0 +1,46 @@ +package com.baeldung.jersey.server; + +import javax.ws.rs.FormParam; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PathParam; + +public class ItemParam { + + @HeaderParam("headerParam") + private String shopKey; + + @PathParam("pathParam") + private String itemId; + + @FormParam("formParam") + private String price; + + public String getShopKey() { + return shopKey; + } + + public void setShopKey(String shopKey) { + this.shopKey = shopKey; + } + + public String getItemId() { + return itemId; + } + + public void setItemId(String itemId) { + this.itemId = itemId; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + @Override + public String toString() { + return "ItemParam{shopKey='" + shopKey + ", itemId='" + itemId + ", price='" + price + '}'; + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/server/Items.java b/jersey/src/main/java/com/baeldung/jersey/server/Items.java new file mode 100644 index 0000000000..c24e6820f5 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/Items.java @@ -0,0 +1,49 @@ +package com.baeldung.jersey.server; + +import javax.ws.rs.*; + +@Path("items") +public class Items { + + @GET + @Path("/cookie") + public String readCookieParam(@CookieParam("cookieParamToRead") String cookieParamToRead) { + return "Cookie parameter value is [" + cookieParamToRead + "]"; + } + + @GET + @Path("/header") + public String readHeaderParam(@HeaderParam("headerParamToRead") String headerParamToRead) { + return "Header parameter value is [" + headerParamToRead + "]"; + } + + @GET + @Path("/path/{pathParamToRead}") + public String readPathParam(@PathParam("pathParamToRead") String pathParamToRead) { + return "Path parameter value is [" + pathParamToRead + "]"; + } + + @GET + @Path("/query") + public String readQueryParam(@QueryParam("queryParamToRead") String queryParamToRead) { + return "Query parameter value is [" + queryParamToRead + "]"; + } + + @POST + @Path("/form") + public String readFormParam(@FormParam("formParamToRead") String formParamToRead) { + return "Form parameter value is [" + formParamToRead + "]"; + } + + @GET + @Path("/matrix") + public String readMatrixParam(@MatrixParam("matrixParamToRead") String matrixParamToRead) { + return "Matrix parameter value is [" + matrixParamToRead + "]"; + } + + @POST + @Path("/bean/{pathParam}") + public String readBeanParam(@BeanParam ItemParam itemParam) { + return itemParam.toString(); + } +} \ No newline at end of file diff --git a/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java b/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java index 4afa086858..1d75508c6d 100644 --- a/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java +++ b/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java @@ -7,12 +7,13 @@ import java.util.logging.Logger; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; +import org.glassfish.jersey.server.ResourceConfig; import com.baeldung.jersey.server.config.ViewApplicationConfig; public class EmbeddedHttpServer { - private static final URI BASE_URI = URI.create("http://localhost:8082/"); + public static final URI BASE_URI = URI.create("http://localhost:8082/"); public static void main(String[] args) { try { @@ -32,4 +33,9 @@ public class EmbeddedHttpServer { } } + + public static HttpServer startServer() { + final ResourceConfig rc = new ResourceConfig().packages("com.baeldung.jersey.server"); + return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI.toString()), rc); + } } diff --git a/jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java b/jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java new file mode 100644 index 0000000000..df85e26b76 --- /dev/null +++ b/jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.jersey.server; + +import static org.junit.Assert.assertEquals; + +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; + +import org.glassfish.grizzly.http.server.HttpServer; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.jersey.server.http.EmbeddedHttpServer; + +public class ItemsUnitTest { + + private HttpServer server; + private WebTarget target; + + @Before + public void setUp() throws Exception { + server = EmbeddedHttpServer.startServer(); + target = ClientBuilder.newClient().target(EmbeddedHttpServer.BASE_URI.toString()); + } + + @After + public void tearDown() throws Exception { + server.stop(); + } + + @Test + public void givenCookieParameter_whenGet_thenReturnsExpectedText() { + String paramValue = "1"; + String responseText = target.path("items/cookie").request().cookie("cookieParamToRead", paramValue).get(String.class); + assertEquals("Cookie parameter value is [" + paramValue + "]", responseText); + } + + @Test + public void givenHeaderParameter_whenGet_thenReturnsExpectedText() { + String paramValue = "2"; + String responseText = target.path("items/header").request().header("headerParamToRead", paramValue).get(String.class); + assertEquals("Header parameter value is [" + paramValue + "]", responseText); + } + + @Test + public void givenPathParameter_whenGet_thenReturnsExpectedText() { + String paramValue = "3"; + String responseText = target.path("items/path/" + paramValue).request().get(String.class); + assertEquals("Path parameter value is [" + paramValue + "]", responseText); + } +} diff --git a/jhipster/jhipster-microservice/car-app/pom.xml b/jhipster/jhipster-microservice/car-app/pom.xml index 529877d448..86d94d0a44 100644 --- a/jhipster/jhipster-microservice/car-app/pom.xml +++ b/jhipster/jhipster-microservice/car-app/pom.xml @@ -1,21 +1,100 @@ 4.0.0 - com.car.app - car-app - car-app - war jhipster-microservice com.baeldung.jhipster 1.0.0-SNAPSHOT + com.car.app + car-app + war + car-app ${maven.version} + + -Djava.security.egd=file:/dev/./urandom -Xmx256m + 3.6.2 + 2.0.0 + 2.5 + 3.5 + 0.4.13 + 1.2 + 5.2.8.Final + 2.6.0 + 0.7.9 + 1.8 + 3.21.0-GA + 1.0.0 + 1.1.0 + 0.7.0 + 3.6 + 2.0.0 + 3.6.2 + 4.8 + jdt_apt + 1.1.0.Final + 2.10 + 1.4.1 + 3.0.1 + yyyyMMddHHmmss + 3.0.0 + 3.1.3 + v6.10.0 + + + + + ${project.build.directory}/test-results + 0.0.20 + false + 3.2.2 + 2.12.1 + 3.2 + + src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* + + S3437,UndocumentedApi,BoldAndItalicTagsCheck + + + src/main/webapp/app/**/*.* + Web:BoldAndItalicTagsCheck + + src/main/java/**/* + squid:S3437 + + src/main/java/**/* + squid:UndocumentedApi + + ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec + ${project.testresult.directory}/coverage/jacoco/jacoco.exec + jacoco + + ${project.testresult.directory}/karma + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.basedir}/src/main/ + ${project.testresult.directory}/surefire-reports + ${project.basedir}/src/test/ + + 2.5.0 + + Camden.SR5 + 2.6.1 + 1.4.10.Final + 1.1.0.Final + v0.21.3 + + @@ -819,83 +898,4 @@ - - -Djava.security.egd=file:/dev/./urandom -Xmx256m - 3.6.2 - 2.0.0 - 2.5 - 3.5 - 0.4.13 - 1.2 - 5.2.8.Final - 2.6.0 - 0.7.9 - 1.8 - 3.21.0-GA - 1.0.0 - 1.1.0 - 0.7.0 - 3.6 - 2.0.0 - 3.6.2 - 4.8 - jdt_apt - 1.1.0.Final - 2.10 - 1.4.1 - 3.0.1 - yyyyMMddHHmmss - 3.0.0 - 3.1.3 - v6.10.0 - - - - - ${project.build.directory}/test-results - 0.0.20 - false - 3.2.2 - 2.12.1 - 3.2 - - src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* - - S3437,UndocumentedApi,BoldAndItalicTagsCheck - - - src/main/webapp/app/**/*.* - Web:BoldAndItalicTagsCheck - - src/main/java/**/* - squid:S3437 - - src/main/java/**/* - squid:UndocumentedApi - - ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec - ${project.testresult.directory}/coverage/jacoco/jacoco.exec - jacoco - - ${project.testresult.directory}/karma - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.basedir}/src/main/ - ${project.testresult.directory}/surefire-reports - ${project.basedir}/src/test/ - - 2.5.0 - - Camden.SR5 - 2.6.1 - 1.4.10.Final - 1.1.0.Final - v0.21.3 - - diff --git a/jhipster/jhipster-microservice/dealer-app/pom.xml b/jhipster/jhipster-microservice/dealer-app/pom.xml index 1eac8a930e..3051399ae6 100644 --- a/jhipster/jhipster-microservice/dealer-app/pom.xml +++ b/jhipster/jhipster-microservice/dealer-app/pom.xml @@ -1,21 +1,99 @@ 4.0.0 - com.dealer.app - dealer-app - dealer-app - war jhipster-microservice com.baeldung.jhipster 1.0.0-SNAPSHOT + com.dealer.app + dealer-app + war + dealer-app ${maven.version} + + -Djava.security.egd=file:/dev/./urandom -Xmx256m + 3.6.2 + 2.0.0 + 2.5 + 3.5 + 0.4.13 + 1.2 + 5.2.8.Final + 2.6.0 + 0.7.9 + 3.21.0-GA + 1.0.0 + 1.1.0 + 0.7.0 + 3.6 + 2.0.0 + 3.6.2 + 4.8 + jdt_apt + 1.1.0.Final + 2.10 + 1.4.1 + 3.0.1 + yyyyMMddHHmmss + 3.0.0 + 3.1.3 + v6.10.0 + + + + + ${project.build.directory}/test-results + 0.0.20 + false + 3.2.2 + 2.12.1 + 3.2 + + src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* + + S3437,UndocumentedApi,BoldAndItalicTagsCheck + + + src/main/webapp/app/**/*.* + Web:BoldAndItalicTagsCheck + + src/main/java/**/* + squid:S3437 + + src/main/java/**/* + squid:UndocumentedApi + + ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec + ${project.testresult.directory}/coverage/jacoco/jacoco.exec + jacoco + + ${project.testresult.directory}/karma + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.basedir}/src/main/ + ${project.testresult.directory}/surefire-reports + ${project.basedir}/src/test/ + + 2.5.0 + + Camden.SR5 + 2.6.1 + 1.4.10.Final + 1.1.0.Final + v0.21.3 + + @@ -813,83 +891,5 @@ - - - -Djava.security.egd=file:/dev/./urandom -Xmx256m - 3.6.2 - 2.0.0 - 2.5 - 3.5 - 0.4.13 - 1.2 - 5.2.8.Final - 2.6.0 - 0.7.9 - 3.21.0-GA - 1.0.0 - 1.1.0 - 0.7.0 - 3.6 - 2.0.0 - 3.6.2 - 4.8 - jdt_apt - 1.1.0.Final - 2.10 - 1.4.1 - 3.0.1 - yyyyMMddHHmmss - 3.0.0 - 3.1.3 - v6.10.0 - - - - - ${project.build.directory}/test-results - 0.0.20 - false - 3.2.2 - 2.12.1 - 3.2 - src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* - - S3437,UndocumentedApi,BoldAndItalicTagsCheck - - - src/main/webapp/app/**/*.* - Web:BoldAndItalicTagsCheck - - src/main/java/**/* - squid:S3437 - - src/main/java/**/* - squid:UndocumentedApi - - ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec - ${project.testresult.directory}/coverage/jacoco/jacoco.exec - jacoco - - ${project.testresult.directory}/karma - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.basedir}/src/main/ - ${project.testresult.directory}/surefire-reports - ${project.basedir}/src/test/ - - 2.5.0 - - Camden.SR5 - 2.6.1 - 1.4.10.Final - 1.1.0.Final - v0.21.3 - - diff --git a/jhipster/jhipster-microservice/gateway-app/pom.xml b/jhipster/jhipster-microservice/gateway-app/pom.xml index babc9e4f24..4e2c19ed2d 100644 --- a/jhipster/jhipster-microservice/gateway-app/pom.xml +++ b/jhipster/jhipster-microservice/gateway-app/pom.xml @@ -1,21 +1,103 @@ 4.0.0 - com.gateway - gateway-app - gateway-app - war jhipster-microservice com.baeldung.jhipster 1.0.0-SNAPSHOT + com.gateway + gateway-app + war + gateway-app ${maven.version} + + -Djava.security.egd=file:/dev/./urandom -Xmx256m + 3.6.2 + 2.0.0 + 3.6.0 + 1.10 + 2.5 + 3.5 + 0.4.13 + 1.3 + 1.2 + 5.2.8.Final + 2.6.0 + 0.7.9 + 3.21.0-GA + 1.0.0 + 1.1.0 + 0.7.0 + 3.6 + 2.0.0 + 3.6.2 + 4.8 + 1.3.0 + jdt_apt + 1.1.0.Final + 2.10 + 1.4.1 + 3.0.1 + yyyyMMddHHmmss + 3.0.0 + 3.1.3 + v6.10.0 + + + + + ${project.build.directory}/test-results + 0.0.20 + false + 3.2.2 + 2.12.1 + 3.2 + + src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* + + S3437,UndocumentedApi,BoldAndItalicTagsCheck + + + src/main/webapp/app/**/*.* + Web:BoldAndItalicTagsCheck + + src/main/java/**/* + squid:S3437 + + src/main/java/**/* + squid:UndocumentedApi + + ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec + ${project.testresult.directory}/coverage/jacoco/jacoco.exec + jacoco + + ${project.testresult.directory}/karma + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.basedir}/src/main/ + ${project.testresult.directory}/surefire-reports + ${project.basedir}/src/test/ + + 2.5.0 + + Camden.SR5 + 2.6.1 + 1.4.10.Final + 1.1.0.Final + v0.21.3 + + @@ -925,87 +1007,5 @@ - - - -Djava.security.egd=file:/dev/./urandom -Xmx256m - 3.6.2 - 2.0.0 - 3.6.0 - 1.10 - 2.5 - 3.5 - 0.4.13 - 1.3 - 1.2 - 5.2.8.Final - 2.6.0 - 0.7.9 - 3.21.0-GA - 1.0.0 - 1.1.0 - 0.7.0 - 3.6 - 2.0.0 - 3.6.2 - 4.8 - 1.3.0 - jdt_apt - 1.1.0.Final - 2.10 - 1.4.1 - 3.0.1 - yyyyMMddHHmmss - 3.0.0 - 3.1.3 - v6.10.0 - - - - - ${project.build.directory}/test-results - 0.0.20 - false - 3.2.2 - 2.12.1 - 3.2 - - src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* - - S3437,UndocumentedApi,BoldAndItalicTagsCheck - - - src/main/webapp/app/**/*.* - Web:BoldAndItalicTagsCheck - - src/main/java/**/* - squid:S3437 - - src/main/java/**/* - squid:UndocumentedApi - - ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec - ${project.testresult.directory}/coverage/jacoco/jacoco.exec - jacoco - - ${project.testresult.directory}/karma - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.basedir}/src/main/ - ${project.testresult.directory}/surefire-reports - ${project.basedir}/src/test/ - - 2.5.0 - - Camden.SR5 - 2.6.1 - 1.4.10.Final - 1.1.0.Final - v0.21.3 - diff --git a/libraries-primitive/README.MD b/libraries-primitive/README.MD new file mode 100644 index 0000000000..f27fb73dd6 --- /dev/null +++ b/libraries-primitive/README.MD @@ -0,0 +1,3 @@ +### Relevant Articles + +- [Guide to FastUtil](https://www.baeldung.com/fastutil) diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/Product.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/Product.java new file mode 100644 index 0000000000..90f90be0c0 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/Product.java @@ -0,0 +1,50 @@ +package com.baeldung.jpa.projections; + +import java.math.BigDecimal; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Product { + @Id + private long id; + private String name; + private String description; + private String category; + private BigDecimal unitPrice; + + public long getId() { + return id; + } + public void setId(long id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public String getCategory() { + return category; + } + public void setCategory(String category) { + this.category = category; + } + public BigDecimal getUnitPrice() { + return unitPrice; + } + public void setUnitPrice(BigDecimal unitPrice) { + this.unitPrice = unitPrice; + } + +} diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/ProductRepository.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/ProductRepository.java new file mode 100644 index 0000000000..bb269e1de6 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/ProductRepository.java @@ -0,0 +1,93 @@ +package com.baeldung.jpa.projections; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; +import javax.persistence.Tuple; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; + +public class ProductRepository { + private EntityManager entityManager; + + public ProductRepository() { + EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-projections"); + entityManager = factory.createEntityManager(); + } + + @SuppressWarnings("unchecked") + public List findAllNamesUsingJPQL() { + Query query = entityManager.createQuery("select name from Product"); + List resultList = query.getResultList(); + return resultList; + } + + @SuppressWarnings("unchecked") + public List findAllIdsUsingJPQL() { + Query query = entityManager.createQuery("select id from Product"); + List resultList = query.getResultList(); + return resultList; + } + + public List findAllNamesUsingCriteriaBuilder() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(String.class); + Root product = query.from(Product.class); + query.select(product.get("name")); + List resultList = entityManager.createQuery(query).getResultList(); + return resultList; + } + + @SuppressWarnings("unchecked") + public List findAllIdAndNamesUsingJPQL() { + Query query = entityManager.createQuery("select id, name from Product"); + List resultList = query.getResultList(); + return resultList; + } + + public List findAllIdAndNamesUsingCriteriaBuilderArray() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(Object[].class); + Root product = query.from(Product.class); + query.select(builder.array(product.get("id"), product.get("name"))); + List resultList = entityManager.createQuery(query).getResultList(); + return resultList; + } + + public List findAllIdNameUnitPriceUsingCriteriaQueryMultiselect() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(Object[].class); + Root product = query.from(Product.class); + query.multiselect(product.get("id"), product.get("name"), product.get("unitPrice")); + List resultList = entityManager.createQuery(query).getResultList(); + return resultList; + } + + public List findAllIdAndNamesUsingCriteriaBuilderTuple() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(Tuple.class); + Root product = query.from(Product.class); + query.select(builder.tuple(product.get("id"), product.get("name"))); + List resultList = entityManager.createQuery(query).getResultList(); + return resultList; + } + + public List findCountByCategoryUsingJPQL() { + Query query = entityManager.createQuery("select p.category, count(p) from Product p group by p.category"); + return query.getResultList(); + } + + public List findCountByCategoryUsingCriteriaBuilder() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(Object[].class); + Root product = query.from(Product.class); + query.multiselect(product.get("category"), builder.count(product)); + query.groupBy(product.get("category")); + List resultList = entityManager.createQuery(query).getResultList(); + return resultList; + } +} diff --git a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml index 9c5543bc3c..298397e39d 100644 --- a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml @@ -147,7 +147,7 @@ - + org.hibernate.jpa.HibernatePersistenceProvider com.baeldung.jpa.entity.Student @@ -163,4 +163,21 @@ + + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.projections.Product + true + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/java-jpa/src/main/resources/products_jpa.sql b/persistence-modules/java-jpa/src/main/resources/products_jpa.sql new file mode 100644 index 0000000000..43bc294f56 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/resources/products_jpa.sql @@ -0,0 +1,4 @@ +insert into product(id, name, description, category) values (1,'Product Name 1','This is Product 1', 'category1'); +insert into product(id, name, description, category) values (2,'Product Name 2','This is Product 2', 'category1'); +insert into product(id, name, description, category) values (3,'Product Name 3','This is Product 3', 'category2'); +insert into product(id, name, description, category) values (4,'Product Name 4','This is Product 4', 'category3'); diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java new file mode 100644 index 0000000000..47cc7cbaec --- /dev/null +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java @@ -0,0 +1,133 @@ +package com.baeldung.jpa.projections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; + +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.Configuration; +import org.hibernate.criterion.Order; +import org.hibernate.criterion.Projections; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class HibernateProjectionsIntegrationTest { + private static Session session; + private static SessionFactory sessionFactory; + private Transaction transaction; + + @BeforeClass + public static void init() { + Configuration configuration = getConfiguration(); + configuration.addAnnotatedClass(Product.class); + sessionFactory = configuration.buildSessionFactory(); + } + + @Before + public void before() { + session = sessionFactory.getCurrentSession(); + transaction = session.beginTransaction(); + } + + @After + public void after() { + if(transaction.isActive()) { + transaction.rollback(); + } + } + + private static Configuration getConfiguration() { + Configuration cfg = new Configuration(); + cfg.setProperty(AvailableSettings.DIALECT, + "org.hibernate.dialect.H2Dialect"); + cfg.setProperty(AvailableSettings.HBM2DDL_AUTO, "none"); + cfg.setProperty(AvailableSettings.DRIVER, "org.h2.Driver"); + cfg.setProperty(AvailableSettings.URL, + "jdbc:h2:mem:myexceptiondb2;DB_CLOSE_DELAY=-1;;INIT=RUNSCRIPT FROM 'src/test/resources/products.sql'"); + cfg.setProperty(AvailableSettings.USER, "sa"); + cfg.setProperty(AvailableSettings.PASS, ""); + cfg.setProperty(AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "thread"); + return cfg; + } + + + @SuppressWarnings("deprecation") + @Test + public void givenProductData_whenIdAndNameProjectionUsingCriteria_thenListOfObjectArrayReturned() { + Criteria criteria = session.createCriteria(Product.class); + criteria = criteria.setProjection(Projections.projectionList() + .add(Projections.id()) + .add(Projections.property("name"))); + List resultList = criteria.list(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals(1L, resultList.get(0)[0]); + assertEquals("Product Name 1", resultList.get(0)[1]); + assertEquals(2L, resultList.get(1)[0]); + assertEquals("Product Name 2", resultList.get(1)[1]); + assertEquals(3L, resultList.get(2)[0]); + assertEquals("Product Name 3", resultList.get(2)[1]); + assertEquals(4L, resultList.get(3)[0]); + assertEquals("Product Name 4", resultList.get(3)[1]); + } + + + @Test + public void givenProductData_whenNameProjectionUsingCriteria_thenListOfStringReturned() { + Criteria criteria = session.createCriteria(Product.class); + criteria = criteria.setProjection(Projections.property("name")); + List resultList = criteria.list(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals("Product Name 1", resultList.get(0)); + assertEquals("Product Name 2", resultList.get(1)); + assertEquals("Product Name 3", resultList.get(2)); + assertEquals("Product Name 4", resultList.get(3)); + } + + @Test + public void givenProductData_whenCountByCategoryUsingCriteria_thenOK() { + Criteria criteria = session.createCriteria(Product.class); + criteria = criteria.setProjection(Projections.projectionList() + .add(Projections.groupProperty("category")) + .add(Projections.rowCount())); + List resultList = criteria.list(); + + assertNotNull(resultList); + assertEquals(3, resultList.size()); + assertEquals("category1", resultList.get(0)[0]); + assertEquals(2L, resultList.get(0)[1]); + assertEquals("category2", resultList.get(1)[0]); + assertEquals(1L, resultList.get(1)[1]); + assertEquals("category3", resultList.get(2)[0]); + assertEquals(1L, resultList.get(2)[1]); + } + + @Test + public void givenProductData_whenCountByCategoryWithAliasUsingCriteria_thenOK() { + Criteria criteria = session.createCriteria(Product.class); + criteria = criteria.setProjection(Projections.projectionList() + .add(Projections.groupProperty("category")) + .add(Projections.alias(Projections.rowCount(), "count"))); + criteria.addOrder(Order.asc("count")); + List resultList = criteria.list(); + + assertNotNull(resultList); + assertEquals(3, resultList.size()); + assertEquals("category2", resultList.get(0)[0]); + assertEquals(1L, resultList.get(0)[1]); + assertEquals("category3", resultList.get(1)[0]); + assertEquals(1L, resultList.get(1)[1]); + assertEquals("category1", resultList.get(2)[0]); + assertEquals(2L, resultList.get(2)[1]); + } +} diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/ProductRepositoryIntegrationTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/ProductRepositoryIntegrationTest.java new file mode 100644 index 0000000000..c9a05709e3 --- /dev/null +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/ProductRepositoryIntegrationTest.java @@ -0,0 +1,105 @@ +package com.baeldung.jpa.projections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + + +public class ProductRepositoryIntegrationTest { + private static ProductRepository productRepository; + + @BeforeClass + public static void once() throws IOException { + productRepository = new ProductRepository(); + } + + @Test + public void givenProductData_whenIdAndNameProjectionUsingJPQL_thenListOfObjectArrayReturned() { + List resultList = productRepository.findAllIdAndNamesUsingJPQL(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals(1L, resultList.get(0)[0]); + assertEquals("Product Name 1", resultList.get(0)[1]); + assertEquals(2L, resultList.get(1)[0]); + assertEquals("Product Name 2", resultList.get(1)[1]); + assertEquals(3L, resultList.get(2)[0]); + assertEquals("Product Name 3", resultList.get(2)[1]); + assertEquals(4L, resultList.get(3)[0]); + assertEquals("Product Name 4", resultList.get(3)[1]); + } + + @Test + public void givenProductData_whenIdAndNameProjectionUsingCriteriaBuilder_thenListOfObjectArrayReturned() { + List resultList = productRepository.findAllIdAndNamesUsingCriteriaBuilderArray(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals(1L, resultList.get(0)[0]); + assertEquals("Product Name 1", resultList.get(0)[1]); + assertEquals(2L, resultList.get(1)[0]); + assertEquals("Product Name 2", resultList.get(1)[1]); + assertEquals(3L, resultList.get(2)[0]); + assertEquals("Product Name 3", resultList.get(2)[1]); + assertEquals(4L, resultList.get(3)[0]); + assertEquals("Product Name 4", resultList.get(3)[1]); + } + + @SuppressWarnings("rawtypes") + @Test + public void givenProductData_whenNameProjectionUsingJPQL_thenListOfStringReturned() { + List resultList = productRepository.findAllNamesUsingJPQL(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals("Product Name 1", resultList.get(0)); + assertEquals("Product Name 2", resultList.get(1)); + assertEquals("Product Name 3", resultList.get(2)); + assertEquals("Product Name 4", resultList.get(3)); + } + + @Test + public void givenProductData_whenNameProjectionUsingCriteriaBuilder_thenListOfStringReturned() { + List resultList = productRepository.findAllNamesUsingCriteriaBuilder(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals("Product Name 1", resultList.get(0)); + assertEquals("Product Name 2", resultList.get(1)); + assertEquals("Product Name 3", resultList.get(2)); + assertEquals("Product Name 4", resultList.get(3)); + } + + @Test + public void givenProductData_whenCountByCategoryUsingJPQL_thenOK() { + List resultList = productRepository.findCountByCategoryUsingJPQL(); + + assertNotNull(resultList); + assertEquals(3, resultList.size()); + assertEquals("category1", resultList.get(0)[0]); + assertEquals(2L, resultList.get(0)[1]); + assertEquals("category2", resultList.get(1)[0]); + assertEquals(1L, resultList.get(1)[1]); + assertEquals("category3", resultList.get(2)[0]); + assertEquals(1L, resultList.get(2)[1]); + } + + @Test + public void givenProductData_whenCountByCategoryUsingCriteriaBuider_thenOK() { + List resultList = productRepository.findCountByCategoryUsingCriteriaBuilder(); + + assertNotNull(resultList); + assertEquals(3, resultList.size()); + assertEquals("category1", resultList.get(0)[0]); + assertEquals(2L, resultList.get(0)[1]); + assertEquals("category2", resultList.get(1)[0]); + assertEquals(1L, resultList.get(1)[1]); + assertEquals("category3", resultList.get(2)[0]); + assertEquals(1L, resultList.get(2)[1]); + } +} diff --git a/persistence-modules/java-jpa/src/test/resources/products.sql b/persistence-modules/java-jpa/src/test/resources/products.sql new file mode 100644 index 0000000000..d38ea1b037 --- /dev/null +++ b/persistence-modules/java-jpa/src/test/resources/products.sql @@ -0,0 +1,5 @@ +create table Product (id bigint not null, category varchar(255), description varchar(255), name varchar(255), unitPrice decimal(19,2), primary key (id)); +insert into product(id, name, description, category) values (1,'Product Name 1','This is Product 1', 'category1'); +insert into product(id, name, description, category) values (2,'Product Name 2','This is Product 2', 'category1'); +insert into product(id, name, description, category) values (3,'Product Name 3','This is Product 3', 'category2'); +insert into product(id, name, description, category) values (4,'Product Name 4','This is Product 4', 'category3'); diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java index 9e7e516735..5f4a36bc0e 100644 --- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java @@ -43,22 +43,22 @@ public class DeleteFromRepositoryUnitTest { public void whenDeleteByIdFromRepository_thenDeletingShouldBeSuccessful() { repository.deleteById(book1.getId()); - assertThat(repository.count() == 1).isTrue(); + assertThat(repository.count()).isEqualTo(1); } @Test public void whenDeleteAllFromRepository_thenRepositoryShouldBeEmpty() { repository.deleteAll(); - assertThat(repository.count() == 0).isTrue(); + assertThat(repository.count()).isEqualTo(0); } @Test @Transactional public void whenDeleteFromDerivedQuery_thenDeletingShouldBeSuccessful() { - repository.deleteByTitle("The Hobbit"); + long deletedRecords = repository.deleteByTitle("The Hobbit"); - assertThat(repository.count() == 1).isTrue(); + assertThat(deletedRecords).isEqualTo(1); } @Test @@ -66,7 +66,7 @@ public class DeleteFromRepositoryUnitTest { public void whenDeleteFromCustomQuery_thenDeletingShouldBeSuccessful() { repository.deleteBooks("The Hobbit"); - assertThat(repository.count() == 1).isTrue(); + assertThat(repository.count()).isEqualTo(1); } } \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java index 56de8749b2..6275ace6e0 100644 --- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java @@ -46,15 +46,15 @@ public class DeleteInRelationshipsUnitTest { public void whenDeletingCategories_thenBooksShouldAlsoBeDeleted() { categoryRepository.deleteAll(); - assertThat(bookRepository.count() == 0).isTrue(); - assertThat(categoryRepository.count() == 0).isTrue(); + assertThat(bookRepository.count()).isEqualTo(0); + assertThat(categoryRepository.count()).isEqualTo(0); } @Test public void whenDeletingBooks_thenCategoriesShouldAlsoBeDeleted() { bookRepository.deleteAll(); - assertThat(bookRepository.count() == 0).isTrue(); - assertThat(categoryRepository.count() == 2).isTrue(); + assertThat(bookRepository.count()).isEqualTo(0); + assertThat(categoryRepository.count()).isEqualTo(2); } } \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java index 8ff6799e31..3b9aa2cc18 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java @@ -9,6 +9,6 @@ public class MultipleDbApplication { public static void main(String[] args) { SpringApplication.run(MultipleDbApplication.class, args); } - + } diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductAutoConfiguration.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductAutoConfiguration.java new file mode 100644 index 0000000000..a6f8f0829f --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductAutoConfiguration.java @@ -0,0 +1,71 @@ +package com.baeldung.multipledb; + +import java.util.HashMap; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; + +/** + * By default, the persistence-multiple-db.properties file is read for + * non auto configuration in PersistenceProductConfiguration. + *

+ * If we need to use persistence-multiple-db-boot.properties and auto configuration + * then uncomment the below @Configuration class and comment out PersistenceProductConfiguration. + */ +//@Configuration +@PropertySource({"classpath:persistence-multiple-db-boot.properties"}) +@EnableJpaRepositories(basePackages = "com.baeldung.multipledb.dao.product", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "productTransactionManager") +@Profile("!tc") +public class PersistenceProductAutoConfiguration { + @Autowired + private Environment env; + + public PersistenceProductAutoConfiguration() { + super(); + } + + // + + @Bean + public LocalContainerEntityManagerFactoryBean productEntityManager() { + final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(productDataSource()); + em.setPackagesToScan("com.baeldung.multipledb.model.product"); + + final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + em.setJpaVendorAdapter(vendorAdapter); + final HashMap properties = new HashMap(); + properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + properties.put("hibernate.dialect", env.getProperty("hibernate.dialect")); + em.setJpaPropertyMap(properties); + + return em; + } + + @Bean + @ConfigurationProperties(prefix="spring.second-datasource") + public DataSource productDataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean + public PlatformTransactionManager productTransactionManager() { + final JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(productEntityManager().getObject()); + return transactionManager; + } + +} diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserAutoConfiguration.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserAutoConfiguration.java new file mode 100644 index 0000000000..e04a1621b2 --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserAutoConfiguration.java @@ -0,0 +1,75 @@ +package com.baeldung.multipledb; + +import java.util.HashMap; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; + +/** + * By default, the persistence-multiple-db.properties file is read for + * non auto configuration in PersistenceUserConfiguration. + *

+ * If we need to use persistence-multiple-db-boot.properties and auto configuration + * then uncomment the below @Configuration class and comment out PersistenceUserConfiguration. + */ +//@Configuration +@PropertySource({"classpath:persistence-multiple-db-boot.properties"}) +@EnableJpaRepositories(basePackages = "com.baeldung.multipledb.dao.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager") +@Profile("!tc") +public class PersistenceUserAutoConfiguration { + @Autowired + private Environment env; + + public PersistenceUserAutoConfiguration() { + super(); + } + + // + + @Primary + @Bean + public LocalContainerEntityManagerFactoryBean userEntityManager() { + final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(userDataSource()); + em.setPackagesToScan("com.baeldung.multipledb.model.user"); + + final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + em.setJpaVendorAdapter(vendorAdapter); + final HashMap properties = new HashMap(); + properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + properties.put("hibernate.dialect", env.getProperty("hibernate.dialect")); + em.setJpaPropertyMap(properties); + + return em; + } + + @Bean + @Primary + @ConfigurationProperties(prefix="spring.datasource") + public DataSource userDataSource() { + return DataSourceBuilder.create().build(); + } + + @Primary + @Bean + public PlatformTransactionManager userTransactionManager() { + final JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(userEntityManager().getObject()); + return transactionManager; + } + +} diff --git a/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties new file mode 100644 index 0000000000..ffca79b3f5 --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties @@ -0,0 +1,11 @@ +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=false +hibernate.cache.use_query_cache=false + +spring.datasource.jdbcUrl=jdbc:h2:mem:spring_jpa_user;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS +spring.datasource.username=sa +spring.datasource.password=sa + +spring.second-datasource.jdbcUrl=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS +spring.second-datasource.username=sa +spring.second-datasource.password=sa diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/JpaMultipleDBIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/JpaMultipleDBIntegrationTest.java index bcc4103d08..6ba10a4d49 100644 --- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/JpaMultipleDBIntegrationTest.java +++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/JpaMultipleDBIntegrationTest.java @@ -12,7 +12,6 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.Transactional; diff --git a/pom.xml b/pom.xml index 03d2e5d763..92876cd07f 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,6 @@ pom - lombok-custom quarkus @@ -392,6 +391,7 @@ core-java-modules/core-java-concurrency-basic core-java-modules/core-java-concurrency-collections core-java-modules/core-java-io + core-java-modules/core-java-nio core-java-modules/core-java-security core-java-modules/core-java-lang-syntax core-java-modules/core-java-lang @@ -1074,6 +1074,7 @@ core-java-modules/core-java-concurrency-basic core-java-modules/core-java-concurrency-collections core-java-modules/core-java-io + core-java-modules/core-java-nio core-java-modules/core-java-security core-java-modules/core-java-lang-syntax core-java-modules/core-java-lang @@ -1526,7 +1527,7 @@ 1.1.7 - 2.22.0 + 2.21.0 3.7.0 1.6.0 1.8 @@ -1537,7 +1538,7 @@ 1.19 1.3 1.6.0 - 2.19.1 + 2.21.0 2.5 1.4 3.0.0 diff --git a/spring-5-webflux/pom.xml b/spring-5-webflux/pom.xml index 3306fd1729..c1f537d2fe 100644 --- a/spring-5-webflux/pom.xml +++ b/spring-5-webflux/pom.xml @@ -28,12 +28,22 @@ + + 1.8 + 2.2.0.M3 + + org.springframework.boot spring-boot-starter-webflux + + org.springframework.boot + spring-boot-starter-rsocket + + org.projectlombok lombok @@ -46,8 +56,8 @@ - junit - junit + io.projectreactor + reactor-test test @@ -60,4 +70,35 @@ + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientApplication.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientApplication.java new file mode 100644 index 0000000000..6f35ec5ee0 --- /dev/null +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientApplication.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.rsocket.client; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +public class ClientApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder() + .main(ClientApplication.class) + .sources(ClientApplication.class) + .profiles("client") + .run(args); + } +} diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientConfiguration.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientConfiguration.java new file mode 100644 index 0000000000..7dd3591cd6 --- /dev/null +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientConfiguration.java @@ -0,0 +1,30 @@ +package com.baeldung.spring.rsocket.client; + +import io.rsocket.RSocket; +import io.rsocket.RSocketFactory; +import io.rsocket.frame.decoder.PayloadDecoder; +import io.rsocket.transport.netty.client.TcpClientTransport; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.rsocket.RSocketRequester; +import org.springframework.messaging.rsocket.RSocketStrategies; +import org.springframework.util.MimeTypeUtils; + +@Configuration +public class ClientConfiguration { + + @Bean + public RSocket rSocket() { + return RSocketFactory.connect() + .mimeType(MimeTypeUtils.APPLICATION_JSON_VALUE, MimeTypeUtils.APPLICATION_JSON_VALUE) + .frameDecoder(PayloadDecoder.ZERO_COPY) + .transport(TcpClientTransport.create(7000)) + .start() + .block(); + } + + @Bean + RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) { + return RSocketRequester.wrap(rSocket(), MimeTypeUtils.APPLICATION_JSON, rSocketStrategies); + } +} diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/MarketDataRestController.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/MarketDataRestController.java new file mode 100644 index 0000000000..3701bd69e9 --- /dev/null +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/MarketDataRestController.java @@ -0,0 +1,47 @@ +package com.baeldung.spring.rsocket.client; + +import com.baeldung.spring.rsocket.model.MarketData; +import com.baeldung.spring.rsocket.model.MarketDataRequest; +import java.util.Random; +import org.reactivestreams.Publisher; +import org.springframework.http.MediaType; +import org.springframework.messaging.rsocket.RSocketRequester; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class MarketDataRestController { + + private final Random random = new Random(); + private final RSocketRequester rSocketRequester; + + public MarketDataRestController(RSocketRequester rSocketRequester) { + this.rSocketRequester = rSocketRequester; + } + + @GetMapping(value = "/current/{stock}") + public Publisher current(@PathVariable("stock") String stock) { + return rSocketRequester.route("currentMarketData") + .data(new MarketDataRequest(stock)) + .retrieveMono(MarketData.class); + } + + @GetMapping(value = "/feed/{stock}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Publisher feed(@PathVariable("stock") String stock) { + return rSocketRequester.route("feedMarketData") + .data(new MarketDataRequest(stock)) + .retrieveFlux(MarketData.class); + } + + @GetMapping(value = "/collect") + public Publisher collect() { + return rSocketRequester.route("collectMarketData") + .data(getMarketData()) + .send(); + } + + private MarketData getMarketData() { + return new MarketData("X", random.nextInt(10)); + } +} diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketData.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketData.java new file mode 100644 index 0000000000..3eeaf449e9 --- /dev/null +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketData.java @@ -0,0 +1,20 @@ +package com.baeldung.spring.rsocket.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MarketData { + + private String stock; + private int currentPrice; + + public static MarketData fromException(Exception e) { + MarketData marketData = new MarketData(); + marketData.setStock(e.getMessage()); + return marketData; + } +} diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketDataRequest.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketDataRequest.java new file mode 100644 index 0000000000..1debbb0870 --- /dev/null +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/model/MarketDataRequest.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.rsocket.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MarketDataRequest { + + private String stock; +} diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRSocketController.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRSocketController.java new file mode 100644 index 0000000000..1ff23966fa --- /dev/null +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRSocketController.java @@ -0,0 +1,40 @@ +package com.baeldung.spring.rsocket.server; + +import com.baeldung.spring.rsocket.model.MarketData; +import com.baeldung.spring.rsocket.model.MarketDataRequest; +import org.springframework.messaging.handler.annotation.MessageExceptionHandler; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.stereotype.Controller; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Controller +public class MarketDataRSocketController { + + private final MarketDataRepository marketDataRepository; + + public MarketDataRSocketController(MarketDataRepository marketDataRepository) { + this.marketDataRepository = marketDataRepository; + } + + @MessageMapping("currentMarketData") + public Mono currentMarketData(MarketDataRequest marketDataRequest) { + return marketDataRepository.getOne(marketDataRequest.getStock()); + } + + @MessageMapping("feedMarketData") + public Flux feedMarketData(MarketDataRequest marketDataRequest) { + return marketDataRepository.getAll(marketDataRequest.getStock()); + } + + @MessageMapping("collectMarketData") + public Mono collectMarketData(MarketData marketData) { + marketDataRepository.add(marketData); + return Mono.empty(); + } + + @MessageExceptionHandler + public Mono handleException(Exception e) { + return Mono.just(MarketData.fromException(e)); + } +} diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRepository.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRepository.java new file mode 100644 index 0000000000..4f30c36c2f --- /dev/null +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/MarketDataRepository.java @@ -0,0 +1,37 @@ +package com.baeldung.spring.rsocket.server; + +import com.baeldung.spring.rsocket.model.MarketData; +import java.time.Duration; +import java.util.Random; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Slf4j +@Component +public class MarketDataRepository { + + private static final int BOUND = 100; + + private Random random = new Random(); + + public Flux getAll(String stock) { + return Flux.fromStream(Stream.generate(() -> getMarketDataResponse(stock))) + .log() + .delayElements(Duration.ofSeconds(1)); + } + + public Mono getOne(String stock) { + return Mono.just(getMarketDataResponse(stock)); + } + + public void add(MarketData marketData) { + log.info("New market data: {}", marketData); + } + + private MarketData getMarketDataResponse(String stock) { + return new MarketData(stock, random.nextInt(BOUND)); + } +} diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/ServerApplication.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/ServerApplication.java new file mode 100644 index 0000000000..4213e315dd --- /dev/null +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/server/ServerApplication.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.rsocket.server; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +public class ServerApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder() + .main(ServerApplication.class) + .sources(ServerApplication.class) + .profiles("server") + .run(args); + } +} diff --git a/spring-5-webflux/src/main/resources/application-client.properties b/spring-5-webflux/src/main/resources/application-client.properties new file mode 100644 index 0000000000..4c00e40deb --- /dev/null +++ b/spring-5-webflux/src/main/resources/application-client.properties @@ -0,0 +1 @@ +server.port=8080 diff --git a/spring-5-webflux/src/main/resources/application-server.properties b/spring-5-webflux/src/main/resources/application-server.properties new file mode 100644 index 0000000000..1e343b5bf5 --- /dev/null +++ b/spring-5-webflux/src/main/resources/application-server.properties @@ -0,0 +1,2 @@ +spring.rsocket.server.port=7000 +server.port=8081 diff --git a/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/client/MarketDataRestControllerIntegrationTest.java b/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/client/MarketDataRestControllerIntegrationTest.java new file mode 100644 index 0000000000..ff00d5ec24 --- /dev/null +++ b/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/client/MarketDataRestControllerIntegrationTest.java @@ -0,0 +1,92 @@ +package com.baeldung.spring.rsocket.client; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.http.MediaType.TEXT_EVENT_STREAM; + +import com.baeldung.spring.rsocket.model.MarketData; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.messaging.rsocket.RSocketRequester; +import org.springframework.messaging.rsocket.RSocketRequester.RequestSpec; +import org.springframework.messaging.rsocket.RSocketRequester.ResponseSpec; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.FluxExchangeResult; +import org.springframework.test.web.reactive.server.WebTestClient; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +@RunWith(SpringRunner.class) +@WebFluxTest(value = MarketDataRestController.class) +public class MarketDataRestControllerIntegrationTest { + + @Autowired + private WebTestClient testClient; + + @MockBean + private RSocketRequester rSocketRequester; + + @Mock + private RequestSpec requestSpec; + + @Mock + private ResponseSpec responseSpec; + + @Test + public void whenInitiatesRequest_ThenGetsResponse() throws Exception { + when(rSocketRequester.route("currentMarketData")).thenReturn(requestSpec); + when(requestSpec.data(any())).thenReturn(responseSpec); + MarketData marketData = new MarketData("X", 1); + when(responseSpec.retrieveMono(MarketData.class)).thenReturn(Mono.just(marketData)); + + testClient.get() + .uri("/current/{stock}", "X") + .exchange() + .expectStatus() + .isOk() + .expectBody(MarketData.class) + .isEqualTo(marketData); + } + + @Test + public void whenInitiatesFireAndForget_ThenGetsNoResponse() throws Exception { + when(rSocketRequester.route("collectMarketData")).thenReturn(requestSpec); + when(requestSpec.data(any())).thenReturn(responseSpec); + when(responseSpec.send()).thenReturn(Mono.empty()); + + testClient.get() + .uri("/collect") + .exchange() + .expectStatus() + .isOk() + .expectBody(Void.class); + } + + @Test + public void whenInitiatesRequest_ThenGetsStream() throws Exception { + when(rSocketRequester.route("feedMarketData")).thenReturn(requestSpec); + when(requestSpec.data(any())).thenReturn(responseSpec); + MarketData firstMarketData = new MarketData("X", 1); + MarketData secondMarketData = new MarketData("X", 2); + when(responseSpec.retrieveFlux(MarketData.class)).thenReturn(Flux.just(firstMarketData, secondMarketData)); + + FluxExchangeResult result = testClient.get() + .uri("/feed/{stock}", "X") + .accept(TEXT_EVENT_STREAM) + .exchange() + .expectStatus() + .isOk() + .returnResult(MarketData.class); + Flux marketDataFlux = result.getResponseBody(); + StepVerifier.create(marketDataFlux) + .expectNext(firstMarketData) + .expectNext(secondMarketData) + .thenCancel() + .verify(); + } +} \ No newline at end of file diff --git a/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/server/MarketDataRSocketControllerLiveTest.java b/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/server/MarketDataRSocketControllerLiveTest.java new file mode 100644 index 0000000000..dcf3b82730 --- /dev/null +++ b/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/server/MarketDataRSocketControllerLiveTest.java @@ -0,0 +1,98 @@ +package com.baeldung.spring.rsocket.server; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; + +import com.baeldung.spring.rsocket.model.MarketData; +import com.baeldung.spring.rsocket.model.MarketDataRequest; +import io.rsocket.RSocket; +import io.rsocket.RSocketFactory; +import io.rsocket.frame.decoder.PayloadDecoder; +import io.rsocket.transport.netty.client.TcpClientTransport; +import java.time.Duration; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Lazy; +import org.springframework.messaging.rsocket.RSocketRequester; +import org.springframework.messaging.rsocket.RSocketStrategies; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.MimeTypeUtils; + +@RunWith(SpringRunner.class) +@SpringBootTest +@TestPropertySource(properties = {"spring.rsocket.server.port=7000"}) +public class MarketDataRSocketControllerLiveTest { + + @Autowired + private RSocketRequester rSocketRequester; + + @SpyBean + private MarketDataRSocketController rSocketController; + + @Test + public void whenGetsFireAndForget_ThenReturnsNoResponse() throws InterruptedException { + final MarketData marketData = new MarketData("X", 1); + rSocketRequester.route("collectMarketData") + .data(marketData) + .send() + .block(Duration.ofSeconds(10)); + + sleepForProcessing(); + verify(rSocketController).collectMarketData(any()); + } + + @Test + public void whenGetsRequest_ThenReturnsResponse() throws InterruptedException { + final MarketDataRequest marketDataRequest = new MarketDataRequest("X"); + rSocketRequester.route("currentMarketData") + .data(marketDataRequest) + .send() + .block(Duration.ofSeconds(10)); + + sleepForProcessing(); + verify(rSocketController).currentMarketData(any()); + } + + @Test + public void whenGetsRequest_ThenReturnsStream() throws InterruptedException { + final MarketDataRequest marketDataRequest = new MarketDataRequest("X"); + rSocketRequester.route("feedMarketData") + .data(marketDataRequest) + .send() + .block(Duration.ofSeconds(10)); + + sleepForProcessing(); + verify(rSocketController).feedMarketData(any()); + } + + private void sleepForProcessing() throws InterruptedException { + Thread.sleep(1000); + } + + @TestConfiguration + public static class ClientConfiguration { + + @Bean + @Lazy + public RSocket rSocket() { + return RSocketFactory.connect() + .mimeType(MimeTypeUtils.APPLICATION_JSON_VALUE, MimeTypeUtils.APPLICATION_JSON_VALUE) + .frameDecoder(PayloadDecoder.ZERO_COPY) + .transport(TcpClientTransport.create(7000)) + .start() + .block(); + } + + @Bean + @Lazy + RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) { + return RSocketRequester.wrap(rSocket(), MimeTypeUtils.APPLICATION_JSON, rSocketStrategies); + } + } +} \ No newline at end of file diff --git a/spring-5-webflux/src/test/java/com/baeldung/spring/webclientrequests/WebClientRequestsUnitTest.java b/spring-5-webflux/src/test/java/com/baeldung/spring/webclientrequests/WebClientRequestsUnitTest.java index 8919daa9fb..353cb24d0a 100644 --- a/spring-5-webflux/src/test/java/com/baeldung/spring/webclientrequests/WebClientRequestsUnitTest.java +++ b/spring-5-webflux/src/test/java/com/baeldung/spring/webclientrequests/WebClientRequestsUnitTest.java @@ -1,5 +1,10 @@ package com.baeldung.spring.webclientrequests; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import java.time.Duration; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -17,8 +22,6 @@ import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.util.DefaultUriBuilderFactory; import reactor.core.publisher.Mono; -import static org.mockito.Mockito.*; - @RunWith(SpringRunner.class) @WebFluxTest public class WebClientRequestsUnitTest { @@ -50,7 +53,8 @@ public class WebClientRequestsUnitTest { public void whenCallSimpleURI_thenURIMatched() { this.webClient.get() .uri("/products") - .retrieve(); + .exchange() + .block(Duration.ofSeconds(1)); verifyCalledUrl("/products"); } @@ -60,7 +64,8 @@ public class WebClientRequestsUnitTest { .uri(uriBuilder -> uriBuilder .path("/products/{id}") .build(2)) - .retrieve(); + .exchange() + .block(Duration.ofSeconds(1)); verifyCalledUrl("/products/2"); } @@ -70,7 +75,8 @@ public class WebClientRequestsUnitTest { .uri(uriBuilder -> uriBuilder .path("/products/{id}/attributes/{attributeId}") .build(2, 13)) - .retrieve(); + .exchange() + .block(Duration.ofSeconds(1)); verifyCalledUrl("/products/2/attributes/13"); } @@ -83,7 +89,8 @@ public class WebClientRequestsUnitTest { .queryParam("color", "black") .queryParam("deliveryDate", "13/04/2019") .build()) - .retrieve(); + .exchange() + .block(Duration.ofSeconds(1)); verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019"); } @@ -96,7 +103,8 @@ public class WebClientRequestsUnitTest { .queryParam("color", "{authorId}") .queryParam("deliveryDate", "{date}") .build("AndroidPhone", "black", "13/04/2019")) - .retrieve(); + .exchange() + .block(Duration.ofSeconds(1)); verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13%2F04%2F2019"); } @@ -107,7 +115,8 @@ public class WebClientRequestsUnitTest { .path("/products/") .queryParam("tag[]", "Snapdragon", "NFC") .build()) - .retrieve(); + .exchange() + .block(Duration.ofSeconds(1)); verifyCalledUrl("/products/?tag%5B%5D=Snapdragon&tag%5B%5D=NFC"); } @@ -119,7 +128,8 @@ public class WebClientRequestsUnitTest { .path("/products/") .queryParam("category", "Phones", "Tablets") .build()) - .retrieve(); + .exchange() + .block(Duration.ofSeconds(1)); verifyCalledUrl("/products/?category=Phones&category=Tablets"); } @@ -130,7 +140,8 @@ public class WebClientRequestsUnitTest { .path("/products/") .queryParam("category", String.join(",", "Phones", "Tablets")) .build()) - .retrieve(); + .exchange() + .block(Duration.ofSeconds(1)); verifyCalledUrl("/products/?category=Phones,Tablets"); } @@ -151,7 +162,8 @@ public class WebClientRequestsUnitTest { .queryParam("color", "black") .queryParam("deliveryDate", "13/04/2019") .build()) - .retrieve(); + .exchange() + .block(Duration.ofSeconds(1)); verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019"); } diff --git a/spring-batch/src/main/java/org/baeldung/batch/App.java b/spring-batch/src/main/java/org/baeldung/batch/App.java index cea4e8d486..8bf58e65d2 100644 --- a/spring-batch/src/main/java/org/baeldung/batch/App.java +++ b/spring-batch/src/main/java/org/baeldung/batch/App.java @@ -3,6 +3,7 @@ package org.baeldung.batch; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -21,7 +22,11 @@ public class App { final Job job = (Job) context.getBean("firstBatchJob"); System.out.println("Starting the batch job"); try { - final JobExecution execution = jobLauncher.run(job, new JobParameters()); + // To enable multiple execution of a job with the same parameters + JobParameters jobParameters = new JobParametersBuilder() + .addString("jobID", String.valueOf(System.currentTimeMillis())) + .toJobParameters(); + final JobExecution execution = jobLauncher.run(job, jobParameters); System.out.println("Job Status : " + execution.getStatus()); System.out.println("Job succeeded"); } catch (final Exception e) { diff --git a/spring-boot-ops-2/src/main/java/com/baeldung/springbootconfiguration/controller/GreetingsController.java b/spring-boot-ops-2/src/main/java/com/baeldung/springbootconfiguration/controller/GreetingsController.java new file mode 100644 index 0000000000..2d73564c4d --- /dev/null +++ b/spring-boot-ops-2/src/main/java/com/baeldung/springbootconfiguration/controller/GreetingsController.java @@ -0,0 +1,14 @@ +package com.baeldung.springbootconfiguration.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class GreetingsController { + + @GetMapping("/greetings/{username}") + public String getGreetings(@PathVariable("username") String userName) { + return "Hello " + userName + ", Good day...!!!"; + } +} diff --git a/spring-boot-ops-2/src/main/resources/application-tomcat.properties b/spring-boot-ops-2/src/main/resources/application-tomcat.properties index d7c1ba9ac3..42d03a066e 100644 --- a/spring-boot-ops-2/src/main/resources/application-tomcat.properties +++ b/spring-boot-ops-2/src/main/resources/application-tomcat.properties @@ -1,5 +1,5 @@ # server configuration -server.port=80 +server.port=4010 server.address=127.0.0.1 ## Error handling configuration @@ -21,3 +21,9 @@ server.tomcat.accesslog.directory=logs server.tomcat.accesslog.file-date-format=yyyy-MM-dd server.tomcat.accesslog.prefix=access_log server.tomcat.accesslog.suffix=.log +server.tomcat.accesslog.pattern=common +server.tomcat.basedir=tomcat + +## Tomcat internal server logs +logging.level.org.apache.tomcat=DEBUG +logging.level.org.apache.catalina=DEBUG \ No newline at end of file diff --git a/spring-boot-ops-2/src/main/resources/application.properties b/spring-boot-ops-2/src/main/resources/application.properties index 8b13789179..fc3fff1d38 100644 --- a/spring-boot-ops-2/src/main/resources/application.properties +++ b/spring-boot-ops-2/src/main/resources/application.properties @@ -1 +1 @@ - +spring.profiles.active=tomcat diff --git a/spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java b/spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java index 94eddc5b3e..702acb5b65 100644 --- a/spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java +++ b/spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java @@ -5,7 +5,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringDataRestApplication { + public static void main(String[] args) { SpringApplication.run(SpringDataRestApplication.class, args); } + } diff --git a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java index 8258c3b7aa..eb5d8d51d4 100644 --- a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java +++ b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java @@ -1,8 +1,5 @@ package com.baeldung.springdatawebsupport.application.controllers; -import com.baeldung.springdatawebsupport.application.entities.User; -import com.baeldung.springdatawebsupport.application.repositories.UserRepository; -import com.querydsl.core.types.Predicate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -11,9 +8,12 @@ import org.springframework.data.domain.Sort; import org.springframework.data.querydsl.binding.QuerydslPredicate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.baeldung.springdatawebsupport.application.entities.User; +import com.baeldung.springdatawebsupport.application.repositories.UserRepository; +import com.querydsl.core.types.Predicate; + @RestController public class UserController { @@ -33,7 +33,7 @@ public class UserController { public Page findAllUsers(Pageable pageable) { return userRepository.findAll(pageable); } - + @GetMapping("/sortedusers") public Page findAllUsersSortedByName() { Pageable pageable = PageRequest.of(0, 5, Sort.by("name")); diff --git a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java index 41d7ed9d98..a20197dc8b 100644 --- a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java +++ b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java @@ -8,7 +8,6 @@ import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Repository; @Repository -public interface UserRepository extends PagingAndSortingRepository, - QuerydslPredicateExecutor { +public interface UserRepository extends PagingAndSortingRepository, QuerydslPredicateExecutor { } diff --git a/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java index db522b1413..e1aff7e09d 100644 --- a/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java @@ -31,44 +31,28 @@ public class UserControllerIntegrationTest { @Test public void whenGetRequestToUsersEndPointWithIdPathVariable_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/users/{id}", "1") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$.id").value("1")); + mockMvc.perform(MockMvcRequestBuilders.get("/users/{id}", "1").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.jsonPath("$.id").value("1")); } @Test public void whenGetRequestToUsersEndPoint_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/users") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$['pageable']['paged']").value("true")); + mockMvc.perform(MockMvcRequestBuilders.get("/users").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.jsonPath("$['pageable']['paged']").value("true")); } @Test public void whenGetRequestToUserEndPointWithNameRequestParameter_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/user") - .param("name", "John") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$['content'][0].['name']").value("John")); + mockMvc.perform(MockMvcRequestBuilders.get("/user").param("name", "John").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$['content'][0].['name']").value("John")); } @Test public void whenGetRequestToSorteredUsersEndPoint_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/sortedusers") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$['sort']['sorted']").value("true")); + mockMvc.perform(MockMvcRequestBuilders.get("/sortedusers").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.jsonPath("$['sort']['sorted']").value("true")); } @Test public void whenGetRequestToFilteredUsersEndPoint_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/filteredusers") - .param("name", "John") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$[0].name").value("John")); + mockMvc.perform(MockMvcRequestBuilders.get("/filteredusers").param("name", "John").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.jsonPath("$[0].name").value("John")); } } diff --git a/spring-rest-full/src/main/java/org/baeldung/web/util/RestPreconditions.java b/spring-rest-full/src/main/java/org/baeldung/web/util/RestPreconditions.java index 4e211ccb10..4f2dedcfa0 100644 --- a/spring-rest-full/src/main/java/org/baeldung/web/util/RestPreconditions.java +++ b/spring-rest-full/src/main/java/org/baeldung/web/util/RestPreconditions.java @@ -31,11 +31,11 @@ public final class RestPreconditions { /** * Check if some value was found, otherwise throw exception. - * - * @param expression - * has value true if found, otherwise false + * + * @param resource + * has value not null to be returned, otherwise throw exception * @throws MyResourceNotFoundException - * if expression is false, means value not found. + * if resource is null, means value not found. */ public static T checkFound(final T resource) { if (resource == null) { diff --git a/spring-security-kerberos/README.md b/spring-security-kerberos/README.md index 0338c2058c..1b77c380db 100644 --- a/spring-security-kerberos/README.md +++ b/spring-security-kerberos/README.md @@ -7,4 +7,4 @@ mvn clean install ``` ### Relevant Articles: -- [Spring Security – Kerberos](http://www.baeldung.com/xxxxxx) +- [Introduction to SPNEGO/Kerberos Authentication in Spring](https://www.baeldung.com/spring-security-kerberos) diff --git a/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java b/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java new file mode 100644 index 0000000000..c73335b49b --- /dev/null +++ b/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java @@ -0,0 +1,43 @@ +package com.baeldung.springsessionmongodb; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.session.data.mongo.MongoOperationsSessionRepository; +import org.springframework.test.context.junit4.SpringRunner; +import springsessionmongodb.SpringSessionMongoDBApplication; + +import java.util.Base64; + + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringSessionMongoDBApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +public class SpringSessionMongoDBIntegrationTest { + + @Autowired + private MongoOperationsSessionRepository repository; + + private TestRestTemplate restTemplate = new TestRestTemplate(); + + @Test + public void givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() { + HttpEntity response = restTemplate. + exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class); + HttpHeaders headers = response.getHeaders(); + String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE); + + Assert.assertEquals(response.getBody(), + repository.findById(getSessionId(set_cookie)).getAttribute("count").toString()); + } + + private String getSessionId(String set_cookie) { + return new String(Base64.getDecoder().decode(set_cookie.split(";")[0].split("=")[1])); + } + +} diff --git a/spring-session/pom.xml b/spring-session/pom.xml index bcdbaf2406..639686c8ee 100644 --- a/spring-session/pom.xml +++ b/spring-session/pom.xml @@ -17,6 +17,7 @@ spring-session-jdbc spring-session-redis + spring-session-mongodb \ No newline at end of file diff --git a/spring-session/spring-session-mongodb/README.md b/spring-session/spring-session-mongodb/README.md new file mode 100644 index 0000000000..ab42e8d120 --- /dev/null +++ b/spring-session/spring-session-mongodb/README.md @@ -0,0 +1,4 @@ +This module is for Spring Session with MONGO DB tutorial. +Jira BAEL-2886 + +### Relevant Articles: diff --git a/spring-session/spring-session-mongodb/pom.xml b/spring-session/spring-session-mongodb/pom.xml new file mode 100644 index 0000000000..714833cf99 --- /dev/null +++ b/spring-session/spring-session-mongodb/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + com.baeldung + spring-session-mongodb + 0.0.1-SNAPSHOT + spring-session-mongodb + jar + Spring Session with MongoDB tutorial + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.session + spring-session-data-mongodb + ${spring-session-data-mongodb.version} + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + 2.1.3.RELEASE + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBApplication.java similarity index 54% rename from apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java rename to spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBApplication.java index 1ac872ea0f..2994efc719 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java +++ b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBApplication.java @@ -1,13 +1,12 @@ -package org.baeldung.examples.olingo4; +package com.baeldung.springsessionmongodb; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class Olingo4SampleApplication { +public class SpringSessionMongoDBApplication { public static void main(String[] args) { - SpringApplication.run(Olingo4SampleApplication.class, args); + SpringApplication.run(SpringSessionMongoDBApplication.class, args); } - } diff --git a/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java new file mode 100644 index 0000000000..1c38f419c3 --- /dev/null +++ b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java @@ -0,0 +1,28 @@ +package com.baeldung.springsessionmongodb.controller; + +import javax.servlet.http.HttpSession; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class SpringSessionMongoDBController { + + @GetMapping("/") + public ResponseEntity count(HttpSession session) { + + Integer counter = (Integer) session.getAttribute("count"); + + if (counter == null) { + counter = 1; + } else { + counter += 1; + } + + session.setAttribute("count", counter); + + return ResponseEntity.ok(counter); + } + +} \ No newline at end of file diff --git a/spring-session/spring-session-mongodb/src/main/resources/application.properties b/spring-session/spring-session-mongodb/src/main/resources/application.properties new file mode 100644 index 0000000000..1b1a6cfbcb --- /dev/null +++ b/spring-session/spring-session-mongodb/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.session.store-type=mongodb +server.port=8080 + +spring.data.mongodb.host=localhost +spring.data.mongodb.port=27017 +spring.data.mongodb.database=springboot-mongo \ No newline at end of file diff --git a/spring-session/spring-session-mongodb/src/main/resources/logback.xml b/spring-session/spring-session-mongodb/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-session/spring-session-mongodb/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java new file mode 100644 index 0000000000..eb9f4164a6 --- /dev/null +++ b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java @@ -0,0 +1,42 @@ +package com.baeldung.springsessionmongodb; + +import java.util.Base64; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.session.data.mongo.MongoOperationsSessionRepository; +import org.springframework.test.context.junit4.SpringRunner; + + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringSessionMongoDBApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +public class SpringSessionMongoDBIntegrationTest { + + @Autowired + private MongoOperationsSessionRepository repository; + + private TestRestTemplate restTemplate = new TestRestTemplate(); + + @Test + public void givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() { + HttpEntity response = restTemplate. + exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class); + HttpHeaders headers = response.getHeaders(); + String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE); + + Assert.assertEquals(response.getBody(), + repository.findById(getSessionId(set_cookie)).getAttribute("count").toString()); + } + + private String getSessionId(String cookie) { + return new String(Base64.getDecoder().decode(cookie.split(";")[0].split("=")[1])); + } + +} diff --git a/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..3c58b2673f --- /dev/null +++ b/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springsessionmongodb.SpringSessionMongoDBApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringSessionMongoDBApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/testing-modules/junit-5-basics/README.md b/testing-modules/junit-5-basics/README.md index a00e2a3f4a..6e44a9c071 100644 --- a/testing-modules/junit-5-basics/README.md +++ b/testing-modules/junit-5-basics/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Get the Path of the /src/test/resources Directory in JUnit](https://www.baeldung.com/junit-src-test-resources-directory-path) +- [Tagging and Filtering JUnit Tests](https://www.baeldung.com/junit-filtering-tests)