├── .gitignore
├── LICENSE
├── README.md
├── circle.yml
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── yet
│ │ └── spring
│ │ └── core
│ │ ├── App.java
│ │ ├── aspects
│ │ ├── ConsoleLoggerLimitAspect.java
│ │ ├── LoggingAspect.java
│ │ └── StatisticsAspect.java
│ │ ├── beans
│ │ ├── Client.java
│ │ ├── Event.java
│ │ └── EventType.java
│ │ ├── loggers
│ │ ├── AbstractLogger.java
│ │ ├── CacheFileEventLogger.java
│ │ ├── CombinedEventLogger.java
│ │ ├── ConsoleEventLogger.java
│ │ ├── DBLogger.java
│ │ ├── EventLogger.java
│ │ └── FileEventLogger.java
│ │ └── util
│ │ ├── AwareBean.java
│ │ └── Monitor.java
└── resources
│ ├── aspects.xml
│ ├── client.properties
│ ├── db.properties
│ ├── db.xml
│ ├── loggers.xml
│ └── spring.xml
└── test
├── java
└── com
│ └── yet
│ └── spring
│ └── core
│ ├── TestApp.java
│ ├── TestContext.java
│ ├── aspects
│ ├── TestConsoleLoggerLimitAspect.java
│ └── TestStatisticsAspect.java
│ ├── beans
│ └── TestEvent.java
│ └── loggers
│ ├── TestCacheFileEventLogger.java
│ ├── TestCombinedEventLogger.java
│ ├── TestConsoleEventLogger.java
│ ├── TestDBLogger.java
│ └── TestFileEventLogger.java
└── resources
└── db_for_test.properties
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | .classpath
3 | .project
4 | /.settings
5 | /.c9
6 | .idea/
7 | *.iml
8 | /derby.log
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Yuriy Tkach
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # spring-basics-course-project
2 | Исходный код небольшого проекта, создание которого происходит во время выполнения практики в онлайн-курсе [Spring Framework - The Basics](https://www.youtube.com/playlist?list=PL6jg6AGdCNaWF-sUH2QDudBRXo54zuN1t) :movie_camera:
3 |
4 | Чтобы посмотреть файлы, относящиеся к определенному уроку, т.е. всё то, что было сделано в предыдущих уроках и на данном уроке, Вы можете сделать checkout тега **lesson#**, где **#** - это номер урока. Например:
5 | * `git clone git@github.com:yuriytkach/spring-basics-course-project.git` - клонируем себе репозиторий
6 | * `cd spring-basics-course-project` - переходим в папку проекта
7 | * `git checkout lesson3 -b branch_lesson3` - получаем файлы для третьего урока в отдельной branch с именем _branch_lesson3_
8 |
9 | :us:
10 |
11 | Source code of the small project that is created during the online course [Spring Framework - The Basics](https://www.youtube.com/playlist?list=PL6jg6AGdCNaWF-sUH2QDudBRXo54zuN1t) :movie_camera:
12 |
13 | To view the files for specific lesson, i.e. everything that was done on previous lessons plus on this lesson, you can just checkout the tag **lesson#** where **#** - is the lesson number. For example:
14 | * `git clone git@github.com:yuriytkach/spring-basics-course-project.git` - cloning the repository
15 | * `cd spring-basics-course-project` - changing directory to project one
16 | * `git checkout lesson3 -b branch_lesson3` - getting files for third lesson in a separate branch with name _branch_lesson3_
17 |
18 |
19 | ## Quick links
20 |
21 | |Item |Link |
22 | |:---------------------|:-----------------------------------------------------------------------------------------|
23 | |Continuous integration| [](https://circleci.com/gh/yuriytkach/spring-basics-course-project) |
24 | |Code coverage | [](https://coveralls.io/github/yuriytkach/spring-basics-course-project?branch=master) |
25 |
--------------------------------------------------------------------------------
/circle.yml:
--------------------------------------------------------------------------------
1 | test:
2 | override:
3 | - mvn -DrepoToken=${repoToken} -P circleci integration-test jacoco:report coveralls:report
4 | post:
5 | - mkdir -p $CIRCLE_TEST_REPORTS/junit/
6 | - find . -type f -regex ".*/target/surefire-reports/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
7 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | com.yet.spring
5 | com.yet.spring.core
6 | 0.13-SNAPSHOT
7 | Spring Basics Course Project
8 | The project created throughout the course 'Spring Framework - The Basics'
9 |
10 |
11 | 3.2.13.RELEASE
12 | 4.12
13 | 2.2.12
14 | 2.4
15 |
16 | 1.8.9
17 |
18 | 10.13.1.1
19 |
20 | 1.8
21 | UTF-8
22 |
23 |
24 |
25 |
26 | circleci
27 |
28 |
29 | ${CIRCLE_ARTIFACTS}
30 |
31 |
32 |
33 |
34 | org.eluder.coveralls
35 | coveralls-maven-plugin
36 | 4.3.0
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | org.springframework
46 | spring-context
47 | ${spring.version}
48 |
49 |
50 | org.springframework
51 | spring-context-support
52 | ${spring.version}
53 |
54 |
55 | org.springframework
56 | spring-tx
57 | ${spring.version}
58 |
59 |
60 | org.springframework
61 | spring-jdbc
62 | ${spring.version}
63 |
64 |
65 |
66 | org.apache.derby
67 | derby
68 | ${derby.version}
69 |
70 |
71 |
72 | org.aspectj
73 | aspectjweaver
74 | ${aspectj.version}
75 |
76 |
77 |
78 | commons-io
79 | commons-io
80 | ${commons.io.version}
81 |
82 |
83 |
84 | junit
85 | junit
86 | ${junit.version}
87 | test
88 |
89 |
90 |
91 | org.mockito
92 | mockito-core
93 | ${mockito.version}
94 | test
95 |
96 |
97 |
98 |
99 |
100 |
101 | org.apache.maven.plugins
102 | maven-compiler-plugin
103 | 3.3
104 |
105 | ${java.version}
106 | ${java.version}
107 | ${java.version}
108 | ${project.build.sourceEncoding}
109 | true
110 | true
111 | true
112 |
113 |
114 |
115 |
116 | org.jacoco
117 | jacoco-maven-plugin
118 | 0.7.9
119 |
120 |
121 | prepare-agent
122 |
123 | prepare-agent
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 | https://github.com/yuriytkach/spring-basics-course-project
133 | Github
134 |
135 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/App.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core;
2 |
3 | import java.util.Map;
4 |
5 | import org.springframework.context.ApplicationContext;
6 | import org.springframework.context.ConfigurableApplicationContext;
7 | import org.springframework.context.support.ClassPathXmlApplicationContext;
8 |
9 | import com.yet.spring.core.beans.Client;
10 | import com.yet.spring.core.beans.Event;
11 | import com.yet.spring.core.beans.EventType;
12 | import com.yet.spring.core.loggers.EventLogger;
13 |
14 | public class App {
15 |
16 | private Client client;
17 |
18 | private EventLogger defaultLogger;
19 |
20 | private Map loggers;
21 |
22 | private String startupMessage;
23 |
24 | public static void main(String[] args) {
25 | ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
26 | "spring.xml", "loggers.xml", "aspects.xml", "db.xml");
27 | App app = (App) ctx.getBean("app");
28 |
29 | System.out.println(app.startupMessage);
30 |
31 | Client client = ctx.getBean(Client.class);
32 | System.out.println("Client says: " + client.getGreeting());
33 |
34 | app.logEvents(ctx);
35 |
36 | ctx.close();
37 | }
38 |
39 | public void logEvents(ApplicationContext ctx) {
40 | Event event = ctx.getBean(Event.class);
41 | logEvent(EventType.INFO, event, "Some event for 1");
42 |
43 | event = ctx.getBean(Event.class);
44 | logEvent(EventType.INFO, event, "One more event for 1");
45 |
46 | event = ctx.getBean(Event.class);
47 | logEvent(EventType.INFO, event, "And one more event for 1");
48 |
49 | event = ctx.getBean(Event.class);
50 | logEvent(EventType.ERROR, event, "Some event for 2");
51 |
52 | event = ctx.getBean(Event.class);
53 | logEvent(null, event, "Some event for 3");
54 | }
55 |
56 | public App() {}
57 |
58 | public App(Client client, EventLogger eventLogger, Map loggers) {
59 | super();
60 | this.client = client;
61 | this.defaultLogger = eventLogger;
62 | this.loggers = loggers;
63 | }
64 |
65 | private void logEvent(EventType eventType, Event event, String msg) {
66 | String message = msg.replaceAll(client.getId(), client.getFullName());
67 | event.setMsg(message);
68 |
69 | EventLogger logger = loggers.get(eventType);
70 | if (logger == null) {
71 | logger = defaultLogger;
72 | }
73 |
74 | logger.logEvent(event);
75 | }
76 |
77 | public void setStartupMessage(String startupMessage) {
78 | this.startupMessage = startupMessage;
79 | }
80 |
81 | public EventLogger getDefaultLogger() {
82 | return defaultLogger;
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/aspects/ConsoleLoggerLimitAspect.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.aspects;
2 |
3 | import org.aspectj.lang.ProceedingJoinPoint;
4 |
5 | import com.yet.spring.core.beans.Event;
6 | import com.yet.spring.core.loggers.EventLogger;
7 |
8 | public class ConsoleLoggerLimitAspect {
9 |
10 | private final int maxCount;
11 |
12 | private final EventLogger otherLogger;
13 |
14 | private int currentCount = 0;
15 |
16 | public ConsoleLoggerLimitAspect(int maxCount, EventLogger otherLogger) {
17 | this.maxCount = maxCount;
18 | this.otherLogger = otherLogger;
19 | }
20 |
21 | public void aroundLogEvent(ProceedingJoinPoint jp, Event evt) throws Throwable {
22 | if (currentCount < maxCount) {
23 | System.out.println("ConsoleEventLogger max count is not reached. Continue...");
24 | currentCount++;
25 | jp.proceed(new Object[] {evt});
26 | } else {
27 | System.out.println("ConsoleEventLogger max count is reached. Logging to " + otherLogger.getName());
28 | otherLogger.logEvent(evt);
29 | }
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/aspects/LoggingAspect.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.aspects;
2 |
3 | import org.aspectj.lang.JoinPoint;
4 | import org.aspectj.lang.annotation.AfterReturning;
5 | import org.aspectj.lang.annotation.AfterThrowing;
6 | import org.aspectj.lang.annotation.Aspect;
7 | import org.aspectj.lang.annotation.Before;
8 | import org.aspectj.lang.annotation.Pointcut;
9 |
10 | @Aspect
11 | public class LoggingAspect {
12 |
13 | @Pointcut("execution(* *.logEvent(..))")
14 | private void allLogEventMethods() {}
15 |
16 | @Pointcut("allLogEventMethods() && within(*.*File*Logger)")
17 | private void logEventInsideFileLoggers() {}
18 |
19 | @Before("allLogEventMethods()")
20 | public void logBefore(JoinPoint joinPoint) {
21 | System.out.println("BEFORE: " +
22 | joinPoint.getTarget().getClass().getSimpleName() + " " +
23 | joinPoint.getSignature().getName());
24 | }
25 |
26 | @AfterReturning(pointcut="allLogEventMethods()",
27 | returning="retVal")
28 | public void logAfter(Object retVal) {
29 | System.out.println("AFTER_RET: " + retVal);
30 | }
31 |
32 | @AfterThrowing(pointcut="allLogEventMethods()",
33 | throwing="ex")
34 | public void logAfterThrow(Throwable ex) {
35 | System.out.println("AFTER_THR: " + ex);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/aspects/StatisticsAspect.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.aspects;
2 |
3 | import java.util.Collections;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 | import java.util.Map.Entry;
7 |
8 | import org.aspectj.lang.JoinPoint;
9 | import org.aspectj.lang.annotation.AfterReturning;
10 | import org.aspectj.lang.annotation.Aspect;
11 | import org.aspectj.lang.annotation.Pointcut;
12 |
13 | @Aspect
14 | public class StatisticsAspect {
15 |
16 | private Map, Integer> counter = new HashMap<>();
17 |
18 | @Pointcut("execution(* *.logEvent(..))")
19 | private void allLogEventMethods() {}
20 |
21 | @AfterReturning("allLogEventMethods()")
22 | public void count(JoinPoint jp) {
23 | Class> clazz = jp.getTarget().getClass();
24 | if (!counter.containsKey(clazz)) {
25 | counter.put(clazz, 0);
26 | }
27 | counter.put(clazz, counter.get(clazz) + 1);
28 | }
29 |
30 | public Map, Integer> getCounter() {
31 | return Collections.unmodifiableMap(counter);
32 | }
33 |
34 | @AfterReturning("execution(* com.yet.spring.core.App.logEvents(..))")
35 | public void outputLoggingCounter() {
36 | System.out.println("Loggers statistics. Number of calls: ");
37 | for (Entry, Integer> entry : counter.entrySet()) {
38 | System.out.println(" " + entry.getKey().getSimpleName() + ": " + entry.getValue());
39 | }
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/beans/Client.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.beans;
2 |
3 | public class Client {
4 |
5 | private String id;
6 |
7 | private String fullName;
8 |
9 | private String greeting;
10 |
11 | public Client(String id, String fullName) {
12 | super();
13 | this.id = id;
14 | this.fullName = fullName;
15 | }
16 |
17 | public String getId() {
18 | return id;
19 | }
20 |
21 | public void setId(String id) {
22 | this.id = id;
23 | }
24 |
25 | public String getFullName() {
26 | return fullName;
27 | }
28 |
29 | public void setFullName(String fullName) {
30 | this.fullName = fullName;
31 | }
32 |
33 | public String getGreeting() {
34 | return greeting;
35 | }
36 |
37 | public void setGreeting(String greeting) {
38 | this.greeting = greeting;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/beans/Event.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.beans;
2 |
3 | import java.text.DateFormat;
4 | import java.time.LocalTime;
5 | import java.util.Date;
6 | import java.util.Objects;
7 | import java.util.concurrent.atomic.AtomicInteger;
8 |
9 | public class Event {
10 |
11 | private static final AtomicInteger AUTO_ID = new AtomicInteger(0);
12 |
13 | public static boolean isDay(int start, int end) {
14 | LocalTime time = LocalTime.now();
15 | return time.getHour() > start && time.getHour() < end;
16 | }
17 |
18 | public static void initAutoId(int id) {
19 | AUTO_ID.set(id);
20 | }
21 |
22 | private int id;
23 | private String msg;
24 | private Date date;
25 |
26 | private DateFormat dateFormat;
27 |
28 | public Event(int id, Date date, String msg) {
29 | this.id = id;
30 | this.date = date;
31 | this.msg = msg;
32 | }
33 |
34 | public Event(Date date, DateFormat df) {
35 | this.id = AUTO_ID.getAndIncrement();
36 |
37 | this.date = date;
38 | this.dateFormat = df;
39 | }
40 |
41 | public String getMsg() {
42 | return msg;
43 | }
44 |
45 | public void setMsg(String msg) {
46 | this.msg = msg;
47 | }
48 |
49 | public int getId() {
50 | return id;
51 | }
52 |
53 | public Date getDate() {
54 | return date;
55 | }
56 |
57 | public DateFormat getDateFormat() {
58 | return dateFormat;
59 | }
60 |
61 | public void setDateFormat(DateFormat dateFormat) {
62 | this.dateFormat = dateFormat;
63 | }
64 |
65 | @Override
66 | public String toString() {
67 | return "Event [id=" + id + ", msg=" + msg + ", date=" + dateFormat.format(date) + "]";
68 | }
69 |
70 | @Override
71 | public int hashCode() {
72 | return Objects.hash(id);
73 | }
74 |
75 | @Override
76 | public boolean equals(Object obj) {
77 | if (this == obj)
78 | return true;
79 | if (obj == null)
80 | return false;
81 | if (getClass() != obj.getClass())
82 | return false;
83 | Event other = (Event) obj;
84 | if (id != other.id)
85 | return false;
86 | return true;
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/beans/EventType.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.beans;
2 |
3 | public enum EventType {
4 |
5 | INFO,
6 | ERROR;
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/loggers/AbstractLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | public abstract class AbstractLogger implements EventLogger {
4 |
5 | private String name;
6 |
7 | @Override
8 | public String getName() {
9 | return name;
10 | }
11 |
12 | public void setName(String name) {
13 | this.name = name;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/loggers/CacheFileEventLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import com.yet.spring.core.beans.Event;
7 |
8 | public class CacheFileEventLogger extends FileEventLogger {
9 |
10 | private int cacheSize;
11 | private List cache;
12 |
13 | public CacheFileEventLogger(String filename, int cacheSize) {
14 | super(filename);
15 | this.cacheSize = cacheSize;
16 | this.cache = new ArrayList(cacheSize);
17 | }
18 |
19 | public void destroy() {
20 | if ( ! cache.isEmpty()) {
21 | writeEventsFromCache();
22 | }
23 | }
24 |
25 | @Override
26 | public void logEvent(Event event) {
27 | cache.add(event);
28 |
29 | if (cache.size() == cacheSize) {
30 | writeEventsFromCache();
31 | cache.clear();
32 | }
33 | }
34 |
35 | private void writeEventsFromCache() {
36 | cache.stream().forEach(super::logEvent);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/loggers/CombinedEventLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import java.util.Collection;
4 | import java.util.Collections;
5 |
6 | import com.yet.spring.core.beans.Event;
7 |
8 | public class CombinedEventLogger extends AbstractLogger {
9 |
10 | private final Collection loggers;
11 |
12 | public CombinedEventLogger(Collection loggers) {
13 | super();
14 | this.loggers = loggers;
15 | }
16 |
17 | @Override
18 | public void logEvent(Event event) {
19 | for (EventLogger eventLogger : loggers) {
20 | eventLogger.logEvent(event);
21 | }
22 | }
23 |
24 | public Collection getLoggers() {
25 | return Collections.unmodifiableCollection(loggers);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/loggers/ConsoleEventLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import com.yet.spring.core.beans.Event;
4 |
5 | public class ConsoleEventLogger extends AbstractLogger {
6 |
7 | @Override
8 | public void logEvent(Event event) {
9 | System.out.println(event.toString());
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/loggers/DBLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import java.sql.Date;
4 | import java.sql.ResultSet;
5 | import java.sql.SQLException;
6 | import java.util.List;
7 | import java.util.stream.Collectors;
8 |
9 | import org.springframework.dao.DataAccessException;
10 | import org.springframework.jdbc.core.JdbcTemplate;
11 | import org.springframework.jdbc.core.RowMapper;
12 |
13 | import com.yet.spring.core.beans.Event;
14 |
15 | public class DBLogger extends AbstractLogger {
16 |
17 | private static final String SQL_ERROR_STATE_SCHEMA_EXISTS = "X0Y68";
18 | private static final String SQL_ERROR_STATE_TABLE_EXISTS = "X0Y32";
19 |
20 | private JdbcTemplate jdbcTemplate;
21 | private String schema;
22 |
23 | public DBLogger(JdbcTemplate jdbcTemplate, String schema) {
24 | this.jdbcTemplate = jdbcTemplate;
25 | this.schema = schema.toUpperCase();
26 | }
27 |
28 | public void init() {
29 | createDBSchema();
30 | createTableIfNotExists();
31 | updateEventAutoId();
32 | }
33 |
34 | public void destroy() {
35 | int totalEvents = getTotalEvents();
36 | System.out.println("Total events in the DB: " + totalEvents);
37 |
38 | List allEvents = getAllEvents();
39 | String allEventIds = allEvents.stream()
40 | .map(Event::getId)
41 | .map(String::valueOf)
42 | .collect(Collectors.joining(", "));
43 | System.out.println("All DB Event ids: " + allEventIds);
44 | }
45 |
46 | private void createDBSchema() {
47 | try {
48 | jdbcTemplate.update("CREATE SCHEMA " + schema);
49 | } catch (DataAccessException e) {
50 | Throwable causeException = e.getCause();
51 | if (causeException instanceof SQLException) {
52 | SQLException sqlException = (SQLException) causeException;
53 | if (sqlException.getSQLState().equals(SQL_ERROR_STATE_SCHEMA_EXISTS)) {
54 | System.out.println("Schema already exists");
55 | } else {
56 | throw e;
57 | }
58 | } else {
59 | throw e;
60 | }
61 | }
62 | }
63 |
64 | private void createTableIfNotExists() {
65 | try {
66 | jdbcTemplate.update("CREATE TABLE t_event (" + "id INT NOT NULL PRIMARY KEY," + "date TIMESTAMP,"
67 | + "msg VARCHAR(255)" + ")");
68 |
69 | System.out.println("Created table t_event");
70 | } catch (DataAccessException e) {
71 | Throwable causeException = e.getCause();
72 | if (causeException instanceof SQLException) {
73 | SQLException sqlException = (SQLException) causeException;
74 | if (sqlException.getSQLState().equals(SQL_ERROR_STATE_TABLE_EXISTS)) {
75 | System.out.println("Table already exists");
76 | } else {
77 | throw e;
78 | }
79 | } else {
80 | throw e;
81 | }
82 | }
83 | }
84 |
85 | private void updateEventAutoId() {
86 | int maxId = getMaxId();
87 | Event.initAutoId(maxId + 1);
88 | System.out.println("Initialized Event.AUTO_ID to " + maxId);
89 | }
90 |
91 | private int getMaxId() {
92 | Integer count = jdbcTemplate.queryForObject("select max(id) from t_event", Integer.class);
93 | return count != null ? count.intValue() : 0;
94 | }
95 |
96 | @Override
97 | public void logEvent(Event event) {
98 | jdbcTemplate.update("INSERT INTO t_event (id, date, msg) VALUES (?,?,?)", event.getId(), event.getDate(),
99 | event.toString());
100 | System.out.println("Saved to DB event with id " + event.getId());
101 | }
102 |
103 | public int getTotalEvents() {
104 | Integer count = jdbcTemplate.queryForObject("select count(*) from t_event", Integer.class);
105 | return count != null ? count.intValue() : 0;
106 | }
107 |
108 | public List getAllEvents() {
109 | List list = jdbcTemplate.query("select * from t_event", new RowMapper() {
110 | @Override
111 | public Event mapRow(ResultSet rs, int rowNum) throws SQLException {
112 | Integer id = rs.getInt("id");
113 | Date date = rs.getDate("date");
114 | String msg = rs.getString("msg");
115 | Event event = new Event(id, new Date(date.getTime()), msg);
116 | return event;
117 | }
118 | });
119 | return list;
120 | }
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/loggers/EventLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import com.yet.spring.core.beans.Event;
4 |
5 | public interface EventLogger {
6 |
7 | public void logEvent(Event event);
8 |
9 | public String getName();
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/loggers/FileEventLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | import org.apache.commons.io.FileUtils;
7 |
8 | import com.yet.spring.core.beans.Event;
9 |
10 | public class FileEventLogger extends AbstractLogger {
11 |
12 | private File file;
13 |
14 | private String filename;
15 |
16 | public FileEventLogger(String filename) {
17 | this.filename = filename;
18 | }
19 |
20 | public void init() throws IOException {
21 | file = new File(filename);
22 | if (file.exists() && !file.canWrite()) {
23 | throw new IllegalArgumentException("Can't write to file " + filename);
24 | } else if (!file.exists()) {
25 | file.createNewFile();
26 | }
27 | }
28 |
29 | @Override
30 | public void logEvent(Event event) {
31 | try {
32 | FileUtils.writeStringToFile(file, event.toString() + "\n", true);
33 | } catch (IOException e) {
34 | e.printStackTrace();
35 | }
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/util/AwareBean.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.util;
2 |
3 | import org.springframework.beans.BeansException;
4 | import org.springframework.beans.factory.BeanNameAware;
5 | import org.springframework.context.ApplicationContext;
6 | import org.springframework.context.ApplicationContextAware;
7 | import org.springframework.context.ApplicationEventPublisher;
8 | import org.springframework.context.ApplicationEventPublisherAware;
9 |
10 | public class AwareBean implements ApplicationContextAware, BeanNameAware,
11 | ApplicationEventPublisherAware {
12 |
13 | private ApplicationEventPublisher eventPublisher;
14 | private String name;
15 | private ApplicationContext ctx;
16 |
17 | public void init() {
18 | System.out.println(this.getClass().getSimpleName() + " > My name is '"
19 | + name + "'");
20 | if (ctx != null) {
21 | System.out.println(this.getClass().getSimpleName()
22 | + " > My context is " + ctx.getClass().toString());
23 | } else {
24 | System.out.println(this.getClass().getSimpleName()
25 | + " > Context is not set");
26 | }
27 | if (eventPublisher != null) {
28 | System.out.println(this.getClass().getSimpleName()
29 | + " > My eventPublisher is "
30 | + eventPublisher.getClass().toString());
31 | } else {
32 | System.out.println(this.getClass().getSimpleName()
33 | + " > EventPublisher is not set");
34 | }
35 | }
36 |
37 | @Override
38 | public void setApplicationEventPublisher(ApplicationEventPublisher ep) {
39 | this.eventPublisher = ep;
40 | }
41 |
42 | @Override
43 | public void setBeanName(String name) {
44 | this.name = name;
45 | }
46 |
47 | @Override
48 | public void setApplicationContext(ApplicationContext context)
49 | throws BeansException {
50 | this.ctx = context;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/yet/spring/core/util/Monitor.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.util;
2 |
3 | import org.springframework.context.ApplicationEvent;
4 | import org.springframework.context.ApplicationListener;
5 |
6 | public class Monitor implements ApplicationListener {
7 |
8 | @Override
9 | public void onApplicationEvent(ApplicationEvent event) {
10 | System.out.println(event.getClass().getSimpleName() + " > " + event.getSource().toString());
11 | };
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/resources/aspects.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/main/resources/client.properties:
--------------------------------------------------------------------------------
1 | id=1
2 | name=John Smith
3 | greeting=Hello there!
--------------------------------------------------------------------------------
/src/main/resources/db.properties:
--------------------------------------------------------------------------------
1 | jdbc.driverClassName=org.apache.derby.jdbc.EmbeddedDriver
2 | jdbc.url=jdbc:derby:target/db;create=true
3 | jdbc.username=aa
4 | jdbc.password=bb
--------------------------------------------------------------------------------
/src/main/resources/db.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/main/resources/loggers.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
15 |
16 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/main/resources/spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
18 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
38 |
39 |
40 |
41 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/test/java/com/yet/spring/core/TestApp.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core;
2 |
3 | import static org.junit.Assert.assertFalse;
4 | import static org.junit.Assert.assertNotNull;
5 | import static org.junit.Assert.assertNull;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | import java.lang.reflect.InvocationTargetException;
9 | import java.lang.reflect.Method;
10 | import java.text.DateFormat;
11 | import java.util.Collections;
12 | import java.util.Date;
13 | import java.util.HashMap;
14 |
15 | import org.junit.Test;
16 |
17 | import com.yet.spring.core.beans.Client;
18 | import com.yet.spring.core.beans.Event;
19 | import com.yet.spring.core.beans.EventType;
20 | import com.yet.spring.core.loggers.AbstractLogger;
21 | import com.yet.spring.core.loggers.EventLogger;
22 |
23 | public class TestApp {
24 |
25 | private static final String MSG = "Hello";
26 |
27 | @Test
28 | public void testClientNameSubstitution() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
29 | Client client = new Client("25", "Bob");
30 | DummyLogger dummyLogger = new DummyLogger();
31 |
32 | App app = new App(client, dummyLogger, Collections.emptyMap());
33 |
34 | Event event = new Event(new Date(), DateFormat.getDateTimeInstance());
35 |
36 | invokeLogEvent(app, null, event, MSG + " " + client.getId());
37 | assertTrue(dummyLogger.getEvent().getMsg().contains(MSG));
38 | assertTrue(dummyLogger.getEvent().getMsg().contains(client.getFullName()));
39 |
40 | invokeLogEvent(app, null, event, MSG + " 0");
41 | assertTrue(dummyLogger.getEvent().getMsg().contains(MSG));
42 | assertFalse(dummyLogger.getEvent().getMsg().contains(client.getFullName()));
43 | }
44 |
45 | @Test
46 | public void testCorrectLoggerCall() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
47 | Client client = new Client("25", "Bob");
48 | DummyLogger defaultLogger = new DummyLogger();
49 | DummyLogger infoLogger = new DummyLogger();
50 |
51 | @SuppressWarnings("serial")
52 | App app = new App(client, defaultLogger, new HashMap() {{
53 | put(EventType.INFO, infoLogger);
54 | }});
55 |
56 | Event event = new Event(new Date(), DateFormat.getDateTimeInstance());
57 |
58 | invokeLogEvent(app, null, event, MSG + " " + client.getId());
59 | assertNotNull(defaultLogger.getEvent());
60 | assertNull(infoLogger.getEvent());
61 |
62 | defaultLogger.setEvent(null);
63 | infoLogger.setEvent(null);
64 |
65 | invokeLogEvent(app, EventType.ERROR, event, MSG + " " + client.getId());
66 | assertNotNull(defaultLogger.getEvent());
67 | assertNull(infoLogger.getEvent());
68 |
69 | defaultLogger.setEvent(null);
70 | infoLogger.setEvent(null);
71 |
72 | invokeLogEvent(app, EventType.INFO, event, MSG + " 0");
73 | assertNull(defaultLogger.getEvent());
74 | assertNotNull(infoLogger.getEvent());
75 | }
76 |
77 | private void invokeLogEvent(App app, EventType type, Event event, String message) throws NoSuchMethodException,
78 | IllegalAccessException, InvocationTargetException {
79 | Method method = app.getClass().getDeclaredMethod("logEvent", EventType.class, Event.class, String.class);
80 | method.setAccessible(true);
81 | method.invoke(app, type, event, message);
82 | }
83 |
84 | private class DummyLogger extends AbstractLogger {
85 |
86 | private Event event;
87 |
88 | @Override
89 | public void logEvent(Event event) {
90 | this.event = event;
91 | }
92 |
93 | public Event getEvent() {
94 | return event;
95 | }
96 |
97 | public void setEvent(Event event) {
98 | this.event = event;
99 | }
100 |
101 | };
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/src/test/java/com/yet/spring/core/TestContext.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core;
2 |
3 | import static org.junit.Assert.assertEquals;
4 |
5 | import java.util.Collection;
6 | import java.util.List;
7 | import java.util.stream.Collectors;
8 |
9 | import org.junit.BeforeClass;
10 | import org.junit.Test;
11 | import org.springframework.context.ConfigurableApplicationContext;
12 | import org.springframework.context.support.ClassPathXmlApplicationContext;
13 |
14 | import com.yet.spring.core.beans.Client;
15 | import com.yet.spring.core.loggers.EventLogger;
16 |
17 | public class TestContext {
18 |
19 | @BeforeClass
20 | public static void initTestDbProps() {
21 | System.setProperty("DB_PROPS", "classpath:db_for_test.properties");
22 | }
23 |
24 | @Test
25 | public void testPropertyPlaceholderSystemOverride() {
26 | System.setProperty("id", "35");
27 | ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml",
28 | "loggers.xml", "db.xml");
29 | Client client = ctx.getBean(Client.class);
30 | ctx.close();
31 |
32 | assertEquals("35", client.getId());
33 | }
34 |
35 | @Test
36 | public void testLoggersNames() {
37 | ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml",
38 | "loggers.xml", "db.xml");
39 |
40 | EventLogger fileLogger = ctx.getBean("fileEventLogger", EventLogger.class);
41 | EventLogger cacheLogger = ctx.getBean("cacheFileEventLogger", EventLogger.class);
42 | EventLogger combinedLogger = ctx.getBean("combinedEventLogger", EventLogger.class);
43 |
44 | @SuppressWarnings("unchecked")
45 | List combinedLoggers = ctx.getBean("combinedLoggersList", List.class);
46 |
47 | assertEquals(fileLogger.getName() + " with cache", cacheLogger.getName());
48 |
49 | Collection combinedNames = combinedLoggers.stream()
50 | .map(v -> v.getName()).collect(Collectors.toList());
51 |
52 | assertEquals("Combined " + combinedNames, combinedLogger.getName());
53 |
54 | ctx.close();
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/java/com/yet/spring/core/aspects/TestConsoleLoggerLimitAspect.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.aspects;
2 |
3 | import com.yet.spring.core.beans.Event;
4 | import com.yet.spring.core.loggers.EventLogger;
5 | import org.aspectj.lang.ProceedingJoinPoint;
6 | import org.junit.Test;
7 |
8 | import static org.mockito.Mockito.*;
9 |
10 | public class TestConsoleLoggerLimitAspect {
11 |
12 | @Test
13 | public void testAroundLogEvent() throws Throwable {
14 | ProceedingJoinPoint jp = mock(ProceedingJoinPoint.class);
15 | EventLogger mockLogger = mock(EventLogger.class);
16 | Event mockEvent = mock(Event.class);
17 |
18 | when(mockLogger.getName()).thenReturn("MockLogger");
19 |
20 | ConsoleLoggerLimitAspect aspect = new ConsoleLoggerLimitAspect(2, mockLogger);
21 |
22 | aspect.aroundLogEvent(jp, mockEvent);
23 | aspect.aroundLogEvent(jp, mockEvent);
24 | aspect.aroundLogEvent(jp, mockEvent);
25 |
26 | verify(jp, atMost(2)).proceed();
27 | verify(mockLogger, atMost(1)).logEvent(mockEvent);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/java/com/yet/spring/core/aspects/TestStatisticsAspect.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.aspects;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.mockito.Mockito.atMost;
5 | import static org.mockito.Mockito.mock;
6 | import static org.mockito.Mockito.verify;
7 | import static org.mockito.Mockito.when;
8 |
9 | import java.util.Collections;
10 | import java.util.Map;
11 |
12 | import org.aspectj.lang.JoinPoint;
13 | import org.junit.Test;
14 |
15 | import com.yet.spring.core.loggers.CombinedEventLogger;
16 | import com.yet.spring.core.loggers.ConsoleEventLogger;
17 |
18 |
19 | public class TestStatisticsAspect {
20 |
21 | @Test
22 | public void testStatisticCounter() {
23 | JoinPoint jp = mock(JoinPoint.class);
24 |
25 | when(jp.getTarget()).thenReturn(new ConsoleEventLogger())
26 | .thenReturn(new CombinedEventLogger(Collections.emptyList()))
27 | .thenReturn(new ConsoleEventLogger());
28 |
29 | StatisticsAspect aspect = new StatisticsAspect();
30 |
31 | aspect.count(jp);
32 | aspect.count(jp);
33 | aspect.count(jp);
34 |
35 | verify(jp, atMost(3)).getTarget();
36 |
37 | Map, Integer> counters = aspect.getCounter();
38 | assertEquals(2, counters.size());
39 | assertEquals(2, counters.get(ConsoleEventLogger.class).intValue());
40 | assertEquals(1, counters.get(CombinedEventLogger.class).intValue());
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/test/java/com/yet/spring/core/beans/TestEvent.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.beans;
2 |
3 | import static org.junit.Assert.assertTrue;
4 |
5 | import java.text.DateFormat;
6 | import java.util.Date;
7 |
8 | import org.junit.Test;
9 |
10 | import com.yet.spring.core.beans.Event;
11 |
12 | public class TestEvent {
13 |
14 | @Test
15 | public void testToString() {
16 | Date date = new Date();
17 | DateFormat format = DateFormat.getDateInstance();
18 |
19 | Event event = new Event(date, format);
20 |
21 | String str = event.toString();
22 | assertTrue(str.contains(format.format(date)));
23 | }
24 |
25 | @Test
26 | public void testToString2() {
27 | Date date = new Date();
28 | DateFormat format = DateFormat.getDateTimeInstance();
29 |
30 | Event event = new Event(date, format);
31 |
32 | String str = event.toString();
33 | assertTrue(str.contains(format.format(date)));
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/java/com/yet/spring/core/loggers/TestCacheFileEventLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import static org.junit.Assert.assertFalse;
4 | import static org.junit.Assert.assertTrue;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 | import java.text.DateFormat;
9 | import java.util.Date;
10 |
11 | import org.apache.commons.io.FileUtils;
12 | import org.junit.After;
13 | import org.junit.Before;
14 | import org.junit.Test;
15 |
16 | import com.yet.spring.core.beans.Event;
17 |
18 | public class TestCacheFileEventLogger {
19 |
20 | private File file;
21 |
22 | @Before
23 | public void createFile() throws IOException {
24 | this.file = File.createTempFile("test", "CacheFileEventLogger");
25 | }
26 |
27 | @After
28 | public void removeFile() {
29 | file.delete();
30 | }
31 |
32 | @Test
33 | public void testLogEvent() throws IOException {
34 | Event event = new Event(new Date(), DateFormat.getDateInstance());
35 | CacheFileEventLogger logger = new CacheFileEventLogger(file.getAbsolutePath(), 2);
36 | logger.init();
37 |
38 | String contents = FileUtils.readFileToString(this.file);
39 | assertTrue("File is empty initially", contents.isEmpty());
40 |
41 | logger.logEvent(event);
42 |
43 | contents = FileUtils.readFileToString(this.file);
44 | assertTrue("File is empty as events in cache", contents.isEmpty());
45 |
46 | logger.logEvent(event);
47 |
48 | contents = FileUtils.readFileToString(this.file);
49 | assertFalse("File not empty, cache was dumped", contents.isEmpty());
50 | }
51 |
52 | @Test
53 | public void testDestroy() throws IOException {
54 | Event event = new Event(new Date(), DateFormat.getDateInstance());
55 | CacheFileEventLogger logger = new CacheFileEventLogger(file.getAbsolutePath(), 2);
56 | logger.init();
57 |
58 | String contents = FileUtils.readFileToString(this.file);
59 | assertTrue("File is empty initially", contents.isEmpty());
60 |
61 | logger.logEvent(event);
62 |
63 | contents = FileUtils.readFileToString(this.file);
64 | assertTrue("File is empty as events in cache", contents.isEmpty());
65 |
66 | logger.destroy();
67 |
68 | contents = FileUtils.readFileToString(this.file);
69 | assertFalse("File not empty, cache was dumped", contents.isEmpty());
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/src/test/java/com/yet/spring/core/loggers/TestCombinedEventLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import com.yet.spring.core.beans.Event;
4 | import org.junit.Assert;
5 | import org.junit.Before;
6 | import org.junit.Test;
7 |
8 | import java.util.Collection;
9 | import java.util.stream.Collectors;
10 | import java.util.stream.Stream;
11 |
12 | import static org.mockito.Mockito.atMost;
13 | import static org.mockito.Mockito.mock;
14 | import static org.mockito.Mockito.verify;
15 |
16 | public class TestCombinedEventLogger {
17 |
18 | private Collection loggers;
19 |
20 | @Before
21 | public void createLoggers() {
22 | loggers = Stream.of(
23 | mock(EventLogger.class),
24 | mock(EventLogger.class)
25 | ).collect(Collectors.toList());
26 | }
27 |
28 | @Test
29 | public void testCallingAllLoggers() {
30 | Event event = mock(Event.class);
31 |
32 | CombinedEventLogger combinedEventLogger = new CombinedEventLogger(loggers);
33 | combinedEventLogger.logEvent(event);
34 |
35 | loggers.forEach(logger -> verify(logger, atMost(1)).logEvent(event));
36 | }
37 |
38 | /* Do we really need this test of a setter?! :) */
39 | @Test
40 | public void testAllLoggersReturnedInSetter() {
41 | CombinedEventLogger combinedEventLogger = new CombinedEventLogger(loggers);
42 | combinedEventLogger.getLoggers()
43 | .stream()
44 | .map(logger -> loggers.contains(logger))
45 | .forEach(Assert::assertTrue);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/com/yet/spring/core/loggers/TestConsoleEventLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.PrintStream;
5 | import java.text.DateFormat;
6 | import java.util.Date;
7 |
8 | import org.junit.After;
9 | import org.junit.Assert;
10 | import org.junit.Before;
11 | import org.junit.Test;
12 |
13 | import com.yet.spring.core.beans.Event;
14 | import com.yet.spring.core.loggers.ConsoleEventLogger;
15 |
16 | public class TestConsoleEventLogger {
17 |
18 | private static final String MSG = "Message";
19 | private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
20 |
21 | private PrintStream stdout;
22 |
23 | @Before
24 | public void setUpStreams() {
25 | stdout = System.out;
26 | System.setOut(new PrintStream(outContent));
27 | }
28 |
29 | @After
30 | public void cleanUpStreams() {
31 | System.setOut(stdout);
32 | }
33 |
34 | @Test
35 | public void testLogEvent() {
36 | ConsoleEventLogger logger = new ConsoleEventLogger();
37 | Date date = new Date();
38 | Event event = new Event(date, DateFormat.getDateTimeInstance());
39 | event.setMsg(MSG);
40 |
41 | logger.logEvent(event);
42 |
43 | Assert.assertTrue(outContent.toString().contains(MSG));
44 |
45 | Assert.assertEquals(event.toString().trim(), outContent.toString().trim());
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/java/com/yet/spring/core/loggers/TestDBLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import java.util.List;
6 |
7 | import org.junit.After;
8 | import org.junit.Before;
9 | import org.junit.BeforeClass;
10 | import org.junit.Test;
11 | import org.springframework.context.ConfigurableApplicationContext;
12 | import org.springframework.context.support.ClassPathXmlApplicationContext;
13 |
14 | import com.yet.spring.core.beans.Event;
15 |
16 | public class TestDBLogger {
17 |
18 | @BeforeClass
19 | public static void initTestDbProps() {
20 | System.setProperty("DB_PROPS", "classpath:db_for_test.properties");
21 | Event.initAutoId(-1);
22 | }
23 |
24 | private ConfigurableApplicationContext ctx;
25 |
26 | @Before
27 | public void createContext() {
28 | ctx = new ClassPathXmlApplicationContext("spring.xml",
29 | "loggers.xml", "db.xml");
30 | }
31 |
32 | @After
33 | public void closeContext() {
34 | ctx.close();
35 | }
36 |
37 |
38 | @Test
39 | public void testEventAutoIdCounterSet() {
40 | Event event = new Event(null, null);
41 | assertTrue(event.getId() > -1);
42 | }
43 |
44 | @Test
45 | public void testSaveAndGet() {
46 | DBLogger dbLogger = ctx.getBean("dbLogger", DBLogger.class);
47 |
48 | Event event1 = ctx.getBean(Event.class);
49 | event1.setMsg("a");
50 |
51 | dbLogger.logEvent(event1);
52 |
53 | int total = dbLogger.getTotalEvents();
54 | assertEquals(1, total);
55 |
56 | Event event2 = ctx.getBean(Event.class);
57 | event2.setMsg("b");
58 |
59 | dbLogger.logEvent(event2);
60 |
61 | total = dbLogger.getTotalEvents();
62 | assertEquals(2, total);
63 |
64 | List allEvents = dbLogger.getAllEvents();
65 | assertEquals(2, allEvents.size());
66 | assertTrue(allEvents.contains(event1));
67 | assertTrue(allEvents.contains(event2));
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/test/java/com/yet/spring/core/loggers/TestFileEventLogger.java:
--------------------------------------------------------------------------------
1 | package com.yet.spring.core.loggers;
2 |
3 | import static org.junit.Assert.assertFalse;
4 | import static org.junit.Assert.assertTrue;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 | import java.text.DateFormat;
9 | import java.util.Date;
10 |
11 | import org.apache.commons.io.FileUtils;
12 | import org.junit.After;
13 | import org.junit.Before;
14 | import org.junit.Test;
15 |
16 | import com.yet.spring.core.beans.Event;
17 |
18 | public class TestFileEventLogger {
19 |
20 | private File file;
21 |
22 | @Before
23 | public void createFile() throws IOException {
24 | this.file = File.createTempFile("test", "FileEventLogger");
25 | }
26 |
27 | @After
28 | public void removeFile() {
29 | file.delete();
30 | }
31 |
32 | @Test
33 | public void testInit() throws IOException {
34 | FileEventLogger logger = new FileEventLogger(file.getAbsolutePath());
35 | logger.init();
36 | }
37 |
38 | @Test(expected=IllegalArgumentException.class)
39 | public void testInitFail() throws IOException {
40 | file.setReadOnly();
41 | FileEventLogger logger = new FileEventLogger(file.getAbsolutePath());
42 | logger.init();
43 | }
44 |
45 | @Test
46 | public void testLogEvent() throws IOException {
47 | Event event = new Event(new Date(), DateFormat.getDateInstance());
48 | FileEventLogger logger = new FileEventLogger(file.getAbsolutePath());
49 | logger.init();
50 |
51 | String contents = FileUtils.readFileToString(this.file);
52 | assertTrue(contents.isEmpty());
53 |
54 | logger.logEvent(event);
55 |
56 | contents = FileUtils.readFileToString(this.file);
57 | assertFalse(contents.isEmpty());
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/test/resources/db_for_test.properties:
--------------------------------------------------------------------------------
1 | jdbc.driverClassName=org.apache.derby.jdbc.EmbeddedDriver
2 | jdbc.url=jdbc:derby:memory:myDB;create=true
3 | jdbc.username=aa
4 | jdbc.password=bb
--------------------------------------------------------------------------------