Merge pull request from SmartyAnsh/BAEL-3464_Ninja

Bael 3464 ninja
This commit is contained in:
Eric Martin 2019-12-21 17:54:28 -06:00 committed by GitHub
commit f7f100e040
27 changed files with 753 additions and 2 deletions

183
ninja/pom.xml Normal file

@ -0,0 +1,183 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>ninja</artifactId>
<packaging>jar</packaging>
<groupId>com.baeldung</groupId>
<version>1.0.0</version>
<url>http://www.ninjaframework.org</url>
<properties>
<ninja.version>6.5.0</ninja.version>
<jetty.version>9.4.18.v20190429</jetty.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>enforce-banned-dependencies</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<excludes>
<exclude>commons-logging</exclude>
</excludes>
</bannedDependencies>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<configuration>
<webApp>
<contextPath>/</contextPath>
</webApp>
<stopKey>stop</stopKey>
<stopPort>8889</stopPort>
<scanIntervalSeconds>1</scanIntervalSeconds>
<reload>automatic</reload>
<scanTargetPatterns>
<scanTargetPattern>
<directory>target/classes</directory>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>**/*.ftl.html</exclude>
<exclude>assets/**</exclude>
</excludes>
</scanTargetPattern>
</scanTargetPatterns>
<systemProperties>
<systemProperty>
<name>ninja.mode</name>
<value>dev</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
<!-- Allows you to run Ninja via the SuperDevMode. -->
<!-- run "mvn ninja:run" on the command line for the best -->
<!-- development experience. -->
<plugin>
<groupId>org.ninjaframework</groupId>
<artifactId>ninja-maven-plugin</artifactId>
<version>${ninja.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>ninja.standalone.NinjaJetty</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
<dependencies>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.4</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.186</version>
</dependency>
<dependency>
<groupId>org.ninjaframework</groupId>
<artifactId>ninja-standalone</artifactId>
<version>${ninja.version}</version>
</dependency>
<dependency>
<groupId>org.ninjaframework</groupId>
<artifactId>ninja-test-utilities</artifactId>
<version>${ninja.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<!-- Database settings for development -->
<persistence-unit name="dev_unit"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.connection.driver_class" value="org.h2.Driver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.connection.autocommit" value="true" />
<!-- Connection Pooling settings -->
<property name="hibernate.connection.provider_class" value="org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider" />
<property name="hibernate.c3p0.max_size" value="100" />
<property name="hibernate.c3p0.min_size" value="0" />
<property name="hibernate.c3p0.acquire_increment" value="1" />
<property name="hibernate.c3p0.idle_test_period" value="300" />
<property name="hibernate.c3p0.max_statements" value="0" />
<property name="hibernate.c3p0.timeout" value="100" />
</properties>
</persistence-unit>
</persistence>

@ -0,0 +1,3 @@
/* Add additional stylesheets below
-------------------------------------------------- */

@ -0,0 +1,13 @@
package conf;
import java.util.List;
import ninja.Filter;
public class Filters implements ninja.application.ApplicationFilters {
@Override
public void addFilters(List<Class<? extends Filter>> filters) {
// Add your application - wide filters here
// filters.add(MyFilter.class);
}
}

@ -0,0 +1,18 @@
package conf;
import com.google.inject.AbstractModule;
import com.google.inject.Singleton;
import services.UserService;
import services.UserServiceImpl;
@Singleton
public class Module extends AbstractModule {
protected void configure() {
bind(UserService.class).to(UserServiceImpl.class);
}
}

@ -0,0 +1,32 @@
package conf;
import ninja.AssetsController;
import ninja.Router;
import ninja.application.ApplicationRoutes;
import controllers.ApplicationController;
public class Routes implements ApplicationRoutes {
@Override
public void init(Router router) {
router.GET().route("/index").with(ApplicationController::index);
router.GET().route("/home").with(ApplicationController::home);
router.GET().route("/hello").with(ApplicationController::helloWorld);
router.GET().route("/userJson").with(ApplicationController::userJson);
router.GET().route("/createUser").with(ApplicationController::createUser);
router.GET().route("/flash").with(ApplicationController::showFlashMsg);
router.GET().route("/users").with(ApplicationController::fetchUsers);
router.POST().route("/users").with(ApplicationController::insertUser);
//Assets
router.GET().route("/assets/webjars/{fileName: .*}").with(AssetsController::serveWebJars);
router.GET().route("/assets/{fileName: .*}").with(AssetsController::serveStatic);
//Index
router.GET().route("/.*").with(ApplicationController::index);
}
}

@ -0,0 +1,21 @@
application.name=baeldung ninja dev application
%test.application.name=baeldung ninja test application
%prod.application.name=baeldung ninja application
application.cookie.prefix=NINJA
application.languages=fr,en
application.session.expire_time_in_seconds=3600
application.session.send_only_if_changed=true
application.session.transferred_over_https_only=false
ninja.port=8000
ninja.ssl.port=8001
application.secret = fxSjSL9Q017BSL7gBnkyo2Prln7uXaXIT35gotXRIED8c46OSa8s4QdoIQdTsEtj
# h2 jpa configuration
ninja.jpa.persistence_unit_name=dev_unit
db.connection.url=jdbc:h2:./devDb
db.connection.username=sa
db.connection.password=

@ -0,0 +1,2 @@
header.home=Home!
helloMsg=Hello, welcome to Ninja Framework!

@ -0,0 +1,2 @@
header.home=Accueil!
helloMsg=Bonjour, bienvenue dans Ninja Framework!

@ -0,0 +1,102 @@
package controllers;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.persist.Transactional;
import models.User;
import ninja.Context;
import ninja.Result;
import ninja.Results;
import ninja.i18n.Lang;
import ninja.i18n.Messages;
import ninja.jpa.UnitOfWork;
import ninja.session.FlashScope;
import ninja.validation.JSR303Validation;
import ninja.validation.Validation;
import services.UserService;
@Singleton
public class ApplicationController {
@Inject
Lang lang;
@Inject
Messages msg;
private static Log logger = LogFactory.getLog(ApplicationController.class);
@Inject
Provider<EntityManager> entityManagerProvider;
@Inject
UserService userService;
public Result index() {
return Results.html();
}
public Result userJson() {
HashMap<String, String> userMap = userService.getUserMap();
logger.info(userMap);
return Results.json().render(userMap);
}
public Result helloWorld(Context context) {
Optional<String> language = Optional.of("fr");
String helloMsg = msg.get("helloMsg", language).get();
return Results.text().render(helloMsg);
}
public Result showFlashMsg(FlashScope flashScope) {
flashScope.success("Success message");
flashScope.error("Error message");
return Results.redirect("/home");
}
public Result home() {
return Results.html();
}
public Result createUser() {
return Results.html();
}
@UnitOfWork
public Result fetchUsers() {
EntityManager entityManager = entityManagerProvider.get();
Query q = entityManager.createQuery("SELECT x FROM User x");
List<User> users = (List<User>) q.getResultList();
return Results.json().render(users);
}
@Transactional
public Result insertUser(FlashScope flashScope, @JSR303Validation User user, Validation validation) {
logger.info("Inserting User : " +user);
if (validation.getViolations().size() > 0) {
flashScope.error("Validation Error: User can't be created");
} else {
EntityManager entityManager = entityManagerProvider.get();
entityManager.persist(user);
entityManager.flush();
flashScope.success("User '" + user + "' is created successfully");
}
return Results.redirect("/home");
}
}

@ -0,0 +1,15 @@
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd" updateCheck="false">
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>

@ -0,0 +1,33 @@
<configuration>
<!-- Uncomment to enable file-based logging with
daily (or size exceeding) gzip archival.
Also uncomment the "ROLLING" reference in <root>.
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>mylog.%d{yyyy-MM-dd}.%i.log.gz</FileNamePattern>
<MaxHistory>30</MaxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender> -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
<!-- <appender-ref ref="ROLLING" /> -->
</root>
</configuration>

@ -0,0 +1,25 @@
package models;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
@Entity
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Long id;
@NotNull
public String firstName;
public String email;
public String toString() {
return firstName + " : " + email;
}
}

@ -0,0 +1,9 @@
package services;
import java.util.HashMap;
public interface UserService {
HashMap<String, String> getUserMap();
}

@ -0,0 +1,15 @@
package services;
import java.util.HashMap;
public class UserServiceImpl implements UserService {
@Override
public HashMap<String, String> getUserMap() {
HashMap<String, String> userMap = new HashMap<>();
userMap.put("name", "Norman Lewis");
userMap.put("email", "norman@email.com");
return userMap;
}
}

@ -0,0 +1,12 @@
<#import "../layout/defaultLayout.ftl.html" as layout>
<@layout.myLayout "Create User">
<form method="post" action="users">
First Name : <input type="text" name="firstName"/>
<br/>
Email : <input type="text" name="email"/>
<br/>
<input type="submit" value="Create"/>
</@layout.myLayout>

@ -0,0 +1,9 @@
<#import "../layout/defaultLayout.ftl.html" as layout>
<@layout.myLayout "Home page">
<h1>${i18n("helloMsg")}</h1>
<a href="/userJson">User Json</a>
</@layout.myLayout>

@ -0,0 +1,9 @@
<html>
<head>
<title>Ninja: Index</title>
</head>
<body>
<h1>${i18n("helloMsg")}</h1>
<a href="/userJson">User Json</a>
</body>
</html>

@ -0,0 +1,58 @@
<#macro myLayout title="Layout example">
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>${title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<!-- Le styles -->
<link href="/assets/webjars/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<!-- Optional theme -->
<link rel="stylesheet" href="/assets/webjars/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<!-- Latest compiled and minified JavaScript -->
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
.error-template {padding: 40px 15px;text-align: center;}
</style>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="https://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<#include "header.ftl.html"/>
<#if (flash.error)??>
<div class="alert alert-danger">
${flash.error}
</div>
</#if>
<#if (flash.success)??>
<div class="alert alert-success">
${flash.success}
</div>
</#if>
<#nested/>
<#include "footer.ftl.html"/>
</div> <!-- /container -->
<script type="text/javascript" src="/assets/webjars/jquery/2.1.3/jquery.js"></script>
<script type="text/javascript" src="/assets/webjars/bootstrap/3.3.4/js/bootstrap.min.js"></script>
</body>
</html>
</#macro>

@ -0,0 +1,5 @@
<hr>
<footer>
Built with <a href="http://www.ninjaframework.org">Ninja framework</a>.
</footer>

@ -0,0 +1,20 @@
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="/">${i18n("header.home")}</a></li>
<li class=""><a href="/hello">Hello</a></li>
<li class=""><a href="/users">List User</a></li>
<li class=""><a href="/createUser">Create User</a></li>
</ul>
</div>
<!--/.navbar-collapse -->
</div>
</div>

@ -0,0 +1,18 @@
<#import "../layout/defaultLayout.ftl.html" as layout>
<@layout.myLayout "Error. Forbidden.">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="error-template">
<h1>
Oops!</h1>
<h2>
403 Forbidden</h2>
<div class="error-details">
Sorry, an error has occured. Requested page is forbidden!
</div>
</div>
</div>
</div>
</div>
</@layout.myLayout>

@ -0,0 +1,18 @@
<#import "../layout/defaultLayout.ftl.html" as layout>
<@layout.myLayout "Error. Not found.">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="error-template">
<h1>
Oops!</h1>
<h2>
404 Not Found</h2>
<div class="error-details">
Sorry, an error has occured. Requested page not found!
</div>
</div>
</div>
</div>
</div>
</@layout.myLayout>

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2013 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="true">
<display-name>ninja</display-name>
<listener>
<listener-class>ninja.servlet.NinjaServletListener</listener-class>
</listener>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

@ -0,0 +1,27 @@
package controllers;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;
import org.doctester.testbrowser.Request;
import org.doctester.testbrowser.Response;
import org.junit.Test;
import ninja.NinjaDocTester;
public class ApiControllerDocTesterTest extends NinjaDocTester {
String URL_INDEX = "/";
String URL_HELLO = "/hello";
@Test
public void testGetIndex() {
Response response = makeRequest(Request.GET().url(testServerUrl().path(URL_INDEX)));
assertThat(response.payload, containsString("Hello, welcome to Ninja Framework!"));
}
@Test
public void testGetHello() {
Response response = makeRequest(Request.GET().url(testServerUrl().path(URL_HELLO)));
assertThat(response.payload, containsString("Bonjour, bienvenue dans Ninja Framework!"));
}
}

@ -0,0 +1,32 @@
package controllers;
import static org.junit.Assert.assertEquals;
import javax.inject.Inject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import ninja.NinjaRunner;
import ninja.Result;
import services.UserService;
@RunWith(NinjaRunner.class)
public class ApiControllerMockUnitTest {
@Inject private UserService userService;
ApplicationController applicationController;
@Before
public void setupTest() {
applicationController = new ApplicationController();
applicationController.userService = userService;
}
@Test
public void testThatGetUserJson() {
Result result = applicationController.userJson();
System.out.println(result.getRenderable());
assertEquals(userService.getUserMap().toString(), result.getRenderable().toString());
}
}

@ -590,7 +590,7 @@
<!-- <module>muleesb</module> --> <!-- Fixing in BAEL-10878 -->
<module>mustache</module>
<module>mybatis</module>
<module>ninja</module>
<module>netflix</module>
<module>optaplanner</module>
@ -1225,7 +1225,7 @@
<!-- <module>muleesb</module> --> <!-- Fixing in BAEL-10878 -->
<module>mustache</module>
<module>mybatis</module>
<module>ninja</module>
<module>netflix</module>
<module>optaplanner</module>