JR Utily

final organisation

+ full spring boot application for db-generator
Showing 102 changed files with 2115 additions and 1 deletions
...@@ -28,6 +28,21 @@ ...@@ -28,6 +28,21 @@
28 </dependency> 28 </dependency>
29 29
30 <dependency> 30 <dependency>
31 + <groupId>mysql</groupId>
32 + <artifactId>mysql-connector-java</artifactId>
33 + <!--
34 + <version>5.1.6</version>
35 + -->
36 + </dependency>
37 +
38 +
39 + <dependency>
40 + <groupId>com.h2database</groupId>
41 + <artifactId>h2</artifactId>
42 + <scope>test</scope>
43 + </dependency>
44 +
45 + <dependency>
31 <groupId>org.legrog</groupId> 46 <groupId>org.legrog</groupId>
32 <artifactId>grog-entities</artifactId> 47 <artifactId>grog-entities</artifactId>
33 <version>3.0-SNAPSHOT</version> 48 <version>3.0-SNAPSHOT</version>
...@@ -40,6 +55,13 @@ ...@@ -40,6 +55,13 @@
40 <plugin> 55 <plugin>
41 <groupId>org.springframework.boot</groupId> 56 <groupId>org.springframework.boot</groupId>
42 <artifactId>spring-boot-maven-plugin</artifactId> 57 <artifactId>spring-boot-maven-plugin</artifactId>
58 + <executions>
59 + <execution>
60 + <goals>
61 + <goal>repackage</goal>
62 + </goals>
63 + </execution>
64 + </executions>
43 </plugin> 65 </plugin>
44 </plugins> 66 </plugins>
45 </build> 67 </build>
......
1 +package org.legrog.entities;
2 +
3 +import org.slf4j.Logger;
4 +import org.slf4j.LoggerFactory;
5 +import org.springframework.beans.factory.annotation.Autowired;
6 +import org.springframework.boot.SpringApplication;
7 +import org.springframework.boot.autoconfigure.SpringBootApplication;
8 +
9 +@SpringBootApplication
10 +public class DbGeneratorApplication {
11 +
12 + public static void main(String[] args) {
13 +
14 + Logger logger = LoggerFactory.getLogger(DbGeneratorApplication.class);
15 + logger.info("Create an empty MySQL database - schema/user should already be created, only manage the tables and so.");
16 + logger.info("Needs to now USERNAME, PASSWORD, HOST, PORT and SCHEMA");
17 + logger.info("Usage :");
18 + logger.info(" java -jar target/grog-db-generator-3.0-SNAPSHOT.jar --spring.datasource.username=USERNAME --spring.datasource.password=PASSWORD --spring.datasource.url=\"jdbc:mysql://HOST:PORT/SCHEMA\"");
19 +
20 + SpringApplication.run(DbGeneratorApplication.class, args);
21 + }
22 +}
1 +spring:
2 + application.name: grog-db-generator
3 + profiles.active: prod
4 + main:
5 + web-environment: false
6 + banner-mode: off
7 +
8 +---
9 +
10 +spring:
11 + profiles: prod
12 +
13 + datasource:
14 + driverClassName: com.mysql.jdbc.Driver
15 + initialize: false
16 + url: jdbc:mysql://localhost:3306/grogdev
17 + username: grogdev
18 + password: grogdev
19 +
20 + jpa:
21 + show-sql: true
22 + generate-ddl: true
23 + hibernate:
24 + ddl-auto: create
25 +
26 +---
27 +
28 +spring:
29 + profiles: test
30 +
31 + datasource:
32 + driverClassName: org.h2.Driver
33 + initialize: true
34 +
35 + jpa:
36 + show-sql: true
37 + hibernate:
38 + ddl-auto: create-drop
1 +package org.legrog.entities;
2 +
3 +import org.junit.Test;
4 +import org.junit.runner.RunWith;
5 +import org.springframework.beans.factory.annotation.Autowired;
6 +import org.springframework.boot.test.context.SpringBootTest;
7 +import org.springframework.context.ApplicationContext;
8 +import org.springframework.test.context.ActiveProfiles;
9 +import org.springframework.test.context.junit4.SpringRunner;
10 +
11 +import static org.junit.Assert.*;
12 +
13 +
14 +@RunWith(SpringRunner.class)
15 +@SpringBootTest
16 +@ActiveProfiles(profiles = "test")
17 +public class DbGeneratorApplicationTests {
18 +
19 + @Autowired
20 + ApplicationContext context;
21 +
22 + @Test
23 + public void contextLoads() {
24 + assertNotNull(context);
25 + }
26 +
27 +}
This diff is collapsed. Click to expand it.
1 +package org.legrog.entities;
2 +
3 +import javax.persistence.*;
4 +
5 +/*
6 + Entité persistante représentant les propriétés qui sont paramétrées pour un utilisateur.
7 + Migréee depuis la v2.
8 + */
9 +@Entity
10 +public class AccountAttribute {
11 + @Id
12 + @GeneratedValue(strategy = GenerationType.IDENTITY)
13 + private int userAttributeId;
14 +
15 + public int getUserAttributeId() {
16 + return userAttributeId;
17 + }
18 +
19 + /**
20 + * The linked account.
21 + */
22 + @ManyToOne
23 + private Account account;
24 +
25 + /**
26 + * Retrieve the account this attribute is attached to.
27 + * hibernate.many-to-one
28 + * column="ID_UTILISATEUR"
29 + * class="org.roliste.data.db.Account"
30 + * not-null="true"
31 + * access="property"
32 + * lazy="proxy"
33 + * properties-name="PropertyPerUser"
34 + * foreign-key="FK_ATTRIBUTUTILISATEUR_UTILISATEUR"
35 + * @return the {link org.roliste.data.db.Account} this attribute is attached to.
36 + * Shall not be <code>null</code>.
37 + * see #setAccount(org.roliste.data.db.Account)
38 + */
39 + public Account getAccount() {
40 + return account;
41 + }
42 +
43 + /**
44 + * Set the account this attribute is attached to.
45 + * @param account the new {link org.roliste.data.db.Account} this attribute will be attached to. Shall not be <code>null</code>.
46 + * @see #getAccount()
47 + */
48 + public void setAccount(Account account) {
49 + this.account = account;
50 + }
51 +
52 + /**
53 + * The linked property.
54 + */
55 + @ManyToOne
56 + private AccountProperty accountProperty;
57 +
58 + /**
59 + * Retrieve the property this attribute is attached to.
60 + * hibernate.many-to-one
61 + * column="ID_PROP"
62 + * class="org.roliste.data.db.AccountProperty"
63 + * not-null="true"
64 + * access="property"
65 + * lazy="false"
66 + * properties-name="PropertyPerUser"
67 + * foreign-key="FK_ATTRIBUTUTILISATEUR_PROPRIETE"
68 + * @return the {link org.roliste.data.db.AccountProperty} this attribute is attached to.
69 + * Shall not be <code>null</code>.
70 + * see #setProperty(org.roliste.data.db.AccountProperty)
71 + */
72 + public AccountProperty getProperty() {
73 + return accountProperty;
74 + }
75 +
76 + /**
77 + * Set the property this attribute is attached to.
78 + * @param prop the new {link org.roliste.data.db.AccountProperty} this attribute will be attached to. Shall not be <code>null</code>.
79 + * @see #getProperty()
80 + */
81 + public void setProperty(AccountProperty prop) {
82 + accountProperty = prop;
83 + }
84 +
85 + /**
86 + * The property value.
87 + */
88 + private String value;
89 +
90 + /**
91 + * Returns the property value.
92 + * @return the {@link String} value. If property is known to be some other kind of value, you shall
93 + * convert it yourself. May be <code>null</code>, in cases where the sole existence of the attribute
94 + * is the value, or for unset attributes.
95 + * @see #setValue(String)
96 + * hibernate.property
97 + * column="ATTR_VALUE"
98 + * access="property"
99 + * length="200"
100 + */
101 + public String getValue() {
102 + return value;
103 + }
104 +
105 + /**
106 + * Initializes attribute value.
107 + * @param value the new {@link String} value.
108 + * @see #getValue()
109 + */
110 + public void setValue(String value) {
111 + this.value = value;
112 + }
113 +
114 + /**
115 + * Returns a string representation of this account attribute definition.
116 + * @return a string representing this account attribute definition.
117 + * hidden
118 + */
119 + @Override
120 + public String toString()
121 + {
122 + return "ID_ATTR=" + getUserAttributeId() + " ATTR_PROP=" + accountProperty + " ATTR_VALUE=" + value;
123 + }
124 +
125 +}
1 +package org.legrog.entities;
2 +
3 +import org.springframework.data.jpa.repository.JpaRepository;
4 +
5 +public interface AccountAttributeRepository extends JpaRepository<AccountAttribute, Integer> {
6 +}
1 +package org.legrog.entities;
2 +
3 +import javax.persistence.*;
4 +
5 +/*
6 + Entité persistente représentant la codification des propriétés qui peuvent être paramétrées pour un utilisateur.
7 + Importée depuis la v2.
8 + */
9 +@Entity
10 +public class AccountProperty {
11 + @Id
12 + @GeneratedValue(strategy = GenerationType.IDENTITY) /* Permet la population */
13 + private int userPropertyId;
14 +
15 + /**
16 + *
17 + * hibernate.id
18 + * generator-class="identity"
19 + * column="ID_PROP"
20 + * access="property"
21 + */
22 + public Integer getUserPropertyId() {
23 + return userPropertyId;
24 + }
25 +
26 + /**
27 + * The property name.
28 + */
29 + private String name;
30 +
31 + /**
32 + * Returns the property name.
33 + * @return the {@link String} attribute identifier.
34 + * @see #setName(String)
35 + * hibernate.property
36 + * column="ATTR_NAME"
37 + * not-null="true"
38 + * unique="true"
39 + * access="property"
40 + * length="50"
41 + */
42 + public String getName() {
43 + return name;
44 + }
45 +
46 + /**
47 + * Initializes the property name.
48 + * @param name the new {@link String} identifier.
49 + * @see #getName()
50 + */
51 + public void setName(String name) {
52 + this.name = name;
53 + }
54 +
55 + /**
56 + * The property tag.
57 + */
58 + private String tag;
59 +
60 + /**
61 + * Returns the property tag.
62 + * @return the {@link String} value.
63 + * @see #setTag(String)
64 + * hibernate.property
65 + * column="PROP_TAG"
66 + * access="property"
67 + * length="100"
68 + */
69 + public String getTag() {
70 + return tag;
71 + }
72 +
73 + /**
74 + * Initializes property tag.
75 + * @param tag the new {@link String} tag.
76 + * @see #getTag()
77 + */
78 + public void setTag(String tag) {
79 + this.tag = tag;
80 + }
81 +
82 + /**
83 + * The property validation status.
84 + * A property may be temporarily deactivated.
85 + */
86 + private boolean visible;
87 +
88 + /**
89 + * Indicates if the property is visible / usable.
90 + * If not, users should not be able to access the privileges
91 + * they inherit from having this property set.
92 + * @return the visible flag.
93 + * @see #setVisible(boolean)
94 + * hibernate.property
95 + * column="IND_VISIBLE"
96 + * access="property"
97 + */
98 + public boolean isVisible() {
99 + return visible;
100 + }
101 +
102 + /**
103 + * Initializes the property visible flag.
104 + * @param visible the new flag value.
105 + * @see #isVisible
106 + */
107 + public void setVisible(boolean visible) {
108 + this.visible = visible;
109 + }
110 +
111 + /**
112 + * Returns a string representation of this property definition.
113 + * @return a string representing this property definition.
114 + * hidden
115 + */
116 + @Override
117 + public String toString()
118 + {
119 +
120 + return "ID_PROP=" + getUserPropertyId() + "PROP_NAME=" + name + " PROP_TAG=" + tag + " IND_VISIBLE=" + visible;
121 + }
122 +
123 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.legrog.entities;
2 +
3 +import org.springframework.data.jpa.repository.JpaRepository;
4 +
5 +public interface AccountPropertyRepository extends JpaRepository<AccountProperty, Integer> {
6 +}
1 +package org.legrog.entities;
2 +
3 +import org.springframework.data.jpa.repository.JpaRepository;
4 +
5 +import java.util.List;
6 +
7 +public interface AccountRepository extends JpaRepository<Account, Integer> {
8 + /**
9 + *
10 + * @param integers list of Ids for the Accounts we're looking for
11 + * @return Accounts looked for
12 + */
13 + List<Account> findByUserIdIn(List<Integer> integers);
14 +
15 + /**
16 + *
17 + * @return accounts that have a presentation
18 + */
19 + List<Account> findByPresentationIsNotNull();
20 +}
1 +package org.legrog.entities;
2 +
3 +import java.util.HashSet;
4 +import java.util.Set;
5 +
6 +import javax.persistence.*;
7 +
8 +/**
9 + * The database representation of a account role or group.
10 + * A given {@link Account} may be part of one or more {@link AccountRole}.
11 + * <br/>
12 + * Warning: due to laziness of mapped objects, private attributes of all DB entities shall never be used directly.
13 + * You shall always use the getter/setter methods.
14 + * alias AccountRole
15 + *
16 + */
17 +/*
18 + Importé depuis la v2.
19 + */
20 +@Entity
21 +// TODO évaluer extend v2
22 +public class AccountRole /* extends org.roliste.data.DbEntity */
23 +{
24 + @Id
25 + @GeneratedValue(strategy = GenerationType.IDENTITY)
26 + private int userRoleId;
27 +
28 + /**
29 + * The role identifier.
30 + */
31 + private String rolename;
32 +
33 + /**
34 + * The {@link Account}s for this account role.
35 + */
36 + @ManyToMany(mappedBy = "roles")
37 + private Set<Account> accounts;
38 +
39 + /**
40 + * Builds a new and empty account role definition.
41 + * All attributes are set to their default value.
42 + * <br/>
43 + * Needed by Hibernate for Java reflection.
44 + */
45 + public AccountRole() {
46 + super();
47 + rolename = null;
48 + visible = true;
49 + // no need to synchronize this
50 + accounts = new HashSet<Account>();
51 + }
52 +
53 + public int getUserRoleId() {
54 + return userRoleId;
55 + }
56 +
57 + public void setUserRoleId(int userRoleId) {
58 + this.userRoleId = userRoleId;
59 + }
60 +
61 + /**
62 + * Returns the role identifier.
63 + * @return the {@link String} identifier.
64 + * @see #setRolename(String)
65 + * hibernate.property
66 + * column="NOM_ROLE"
67 + * not-null="true"
68 + * unique="true"
69 + * access="property"
70 + * length="50"
71 + */
72 + public String getRolename() {
73 + return rolename;
74 + }
75 +
76 + /**
77 + * Initializes the role identifier.
78 + * @param name the new {@link String} identifier.
79 + * @see #getRolename()
80 + */
81 + public void setRolename(String name) {
82 + rolename = name;
83 + }
84 +
85 + /**
86 + * The role validation status.
87 + * A role may be temporarily deactivated.
88 + */
89 + private boolean visible;
90 +
91 + /**
92 + * Indicates if the role is visible.
93 + * If not, accounts should not be able to access the privileges
94 + * they inherit from being part of this role.
95 + * @return the visible flag.
96 + * @see #setVisible(boolean)
97 + * hibernate.property
98 + * column="IND_VISIBLE"
99 + * access="property"
100 + */
101 + public boolean isVisible() {
102 + return visible;
103 + }
104 +
105 + /**
106 + * Initializes the account visible flag.
107 + * @param visible the new flag value.
108 + * @see #isVisible
109 + */
110 + public void setVisible(boolean visible) {
111 + this.visible = visible;
112 + }
113 +
114 + /**
115 + * Retrieves the list of {@link Account}s for this account role.
116 + * SHALL be used as a read-only attribute. In particular, avoid
117 + * using {@link Set#add(Object)} or {@link Set#remove(Object)} on
118 + * the returned value without caution.
119 + * @return a {@link Set} of {@link Account}. May be <code>null</code>.
120 + * @see #setAccounts(Set)
121 + * hibernate.many-to-many
122 + * column="UTILISATEUR_FK"
123 + * class="org.roliste.data.db.Person"
124 + * foreign-key="FK_UTILISATEURROLE_UTILISATEUR"
125 + * hibernate.key
126 + * column="ROLE_FK"
127 + * not-null="true"
128 + * foreign-key="FK_UTILISATEURROLE_ROLEUTILISATEUR"
129 + * hibernate.set
130 + * access="property"
131 + * table="role_utilisateur"
132 + * lazy="true"
133 + * inverse="true"
134 + */
135 + public Set<Account> getAccounts() {
136 + return accounts;
137 + }
138 +
139 + /**
140 + * Sets the list of {@link Account}s for this account role.
141 + * @param accounts the new {@link Set} of {@link Account}s. May be
142 + * <code>null</code> (we don't handle the relation from this side).
143 + * @see #getAccounts()
144 + */
145 + protected void setAccounts(Set<Account> accounts) {
146 + this.accounts = accounts;
147 + }
148 +
149 + /**
150 + * Returns a string representation of this account role definition.
151 + * @return a string representing this account role definition.
152 + * hidden
153 + */
154 + @Override
155 + public String toString() {
156 + return "ID_ROLE=" + getUserRoleId() + " NOM_ROLE=" + rolename + " IND_VISIBLE=" + visible;
157 + }
158 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.legrog.entities;
2 +
3 +import org.springframework.data.jpa.repository.JpaRepository;
4 +
5 +public interface AccountRoleRepository extends JpaRepository<AccountRole, Integer> {
6 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.legrog.entities;
2 +
3 +import java.util.List;
4 +
5 +/**
6 + * Search interface for IndexedAccount
7 + */
8 +public interface AccountSearchRepository {
9 + /**
10 + *
11 + * @param string String searched in indexed Accounts
12 + * @return Accounts that match the string
13 + */
14 + List<IndexedAccount> search(String string) throws SearchingException;
15 +
16 + /**
17 + *
18 + * @param indexedAccounts IndexedAccounts to reindex
19 + */
20 + public void reindex(List<IndexedAccount> indexedAccounts) throws IndexingException;
21 +}
1 +package org.legrog.entities;
2 +
3 +import org.apache.solr.client.solrj.SolrClient;
4 +import org.apache.solr.client.solrj.SolrQuery;
5 +import org.apache.solr.client.solrj.SolrServerException;
6 +import org.apache.solr.client.solrj.response.QueryResponse;
7 +import org.apache.solr.client.solrj.response.UpdateResponse;
8 +import org.slf4j.Logger;
9 +import org.slf4j.LoggerFactory;
10 +
11 +import javax.enterprise.inject.Default;
12 +import javax.inject.Inject;
13 +import java.io.IOException;
14 +import java.util.ArrayList;
15 +import java.util.List;
16 +
17 +/**
18 + * Implementation of AccountSearchRepository using SolrJ
19 + */
20 +@Default
21 +public class AccountSearchRepositorySolrj implements AccountSearchRepository {
22 + Logger logger = LoggerFactory.getLogger(getClass());
23 +
24 + SolrClient solrClient;
25 +
26 + protected static String collectionName = "accounts";
27 +
28 + @Inject
29 + AccountSearchRepositorySolrj(SolrClient solrClient) {
30 + this.solrClient = solrClient;
31 + }
32 +
33 + //no args constructor to make it proxyable
34 + AccountSearchRepositorySolrj() {
35 + }
36 +
37 + @Override
38 + public List<IndexedAccount> search(String string) throws SearchingException {
39 + SolrQuery solrQuery = new SolrQuery(string);
40 + QueryResponse queryResponse;
41 + try {
42 + queryResponse = solrClient.query(collectionName, solrQuery);
43 + } catch (IOException ioe) {
44 + throw new SearchingException(ioe);
45 + } catch (SolrServerException sse) {
46 + logger.error("SolrServerException {}", sse);
47 + throw new SearchingException(sse.getRootCause());
48 + }
49 +
50 + if (queryResponse != null) {
51 + return queryResponse.getBeans(IndexedAccount.class);
52 + } else {
53 + return new ArrayList<>();
54 + }
55 + }
56 +
57 + @Override
58 + public void reindex(List<IndexedAccount> indexedAccounts) throws IndexingException {
59 + try {
60 + UpdateResponse updateResponse = solrClient.addBeans(collectionName, indexedAccounts);
61 + solrClient.commit(collectionName);
62 + logger.trace("reindex indexedAccounts SolrJ UpdateResponse {}", updateResponse);
63 + } catch (IOException ioe) {
64 + throw new IndexingException(ioe);
65 + } catch (SolrServerException sse) {
66 + logger.error("SolrServerException {}", sse);
67 + throw new IndexingException(sse.getRootCause());
68 + }
69 + }
70 +}
1 +package org.legrog.entities;
2 +
3 +/**
4 + * Available actions are an enumeration
5 + */
6 +public enum ActionType {
7 + VALIDATE;
8 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.legrog.entities;
2 +
3 +import javax.persistence.*;
4 +
5 +/**
6 + * Country persistence entity
7 + * Id and name seem enough
8 + */
9 +@Entity
10 +public class Country {
11 + @Id
12 + @GeneratedValue(strategy = GenerationType.IDENTITY)
13 + private Integer countryId;
14 + private String countryName;
15 +
16 + public Integer getCountryId() {
17 + return countryId;
18 + }
19 +
20 + public void setCountryId(Integer countryId) {
21 + this.countryId = countryId;
22 + }
23 +
24 + public String getCountryName() {
25 + return countryName;
26 + }
27 +
28 + public void setCountryName(String countryName) {
29 + this.countryName = countryName;
30 + }
31 +
32 + @Override
33 + public String toString()
34 + {
35 + return "ID_PAYS=" + countryId + " LIB_PAYS=" + countryName;
36 + }
37 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.legrog.entities;
2 +
3 +import org.springframework.data.jpa.repository.JpaRepository;
4 +
5 +public interface CountryRepository extends JpaRepository<Country, Integer> {
6 +}
1 +package org.legrog.entities;
2 +
3 +/* DbMaskableEntity en v2, mais je pense le nouveau nom plus clair */
4 +public interface DisplayNameConfigurable {
5 + String getFirstName();
6 +
7 + String getLastName();
8 +
9 + String getNickName();
10 +
11 +/* ScreenName en v2, mais je pense la nouveau nom plus clair */
12 + String getDisplayName();
13 +}
1 +package org.legrog.entities;
2 +
3 +/**
4 + * This enumeration provide options for name masking of authors and users.
5 + * Every {link org.roliste.data.DbMaskableEntity} provide first name, last name and nickname
6 + * capabilities, that may be "masked", thus shown in some specific way depending on chosen
7 + * NameMask.
8 + */
9 +/*
10 + v3 {@link org.legrog.entities.DisplayNameConfigurable}
11 + */
12 +public enum DisplayNameMask
13 +{
14 + PRENOMNOM("Prénom Nom")
15 + {
16 + public String listMask(DisplayNameConfigurable person)
17 + {
18 + return NOMPRENOM.getDisplayName(person);
19 + }
20 +
21 + public String getDisplayName(DisplayNameConfigurable person)
22 + {
23 + StringBuilder sb = new StringBuilder();
24 + if (person.getFirstName() != null)
25 + {
26 + sb.append(person.getFirstName());
27 + }
28 + if (person.getLastName() != null)
29 + {
30 + sb.append(' ');
31 + sb.append(person.getLastName());
32 + }
33 + return sb.toString();
34 + }
35 + },
36 +
37 + NOMPRENOM("Nom, Prénom")
38 + {
39 + public String listMask(DisplayNameConfigurable person)
40 + {
41 + return NOMPRENOM.getDisplayName(person);
42 + }
43 +
44 + public String getDisplayName(DisplayNameConfigurable person)
45 + {
46 + StringBuilder sb = new StringBuilder();
47 + if (person.getLastName() != null)
48 + {
49 + sb.append(person.getLastName());
50 + if (person.getFirstName() != null)
51 + {
52 + sb.append(", ");
53 + sb.append(person.getFirstName());
54 + }
55 + }
56 + else
57 + {
58 + sb.append("!Pas de nom");
59 + }
60 + return sb.toString();
61 + }
62 + },
63 +
64 + PSEUDO("Pseudo")
65 + {
66 + public String listMask(DisplayNameConfigurable person)
67 + {
68 + return PSEUDO.getDisplayName(person);
69 + }
70 +
71 + public String getDisplayName(DisplayNameConfigurable person)
72 + {
73 + StringBuilder sb = new StringBuilder();
74 + if (person.getNickName() != null)
75 + {
76 + sb.append(person.getNickName());
77 + }
78 + else
79 + {
80 + sb.append("!Pas de pseudo");
81 + }
82 + return sb.toString();
83 + }
84 + },
85 +
86 + COMPLET("Prénom 'Pseudo' Nom")
87 + {
88 + public String listMask(DisplayNameConfigurable person)
89 + {
90 + return NOMPRENOM.getDisplayName(person);
91 + }
92 +
93 + public String getDisplayName(DisplayNameConfigurable person)
94 + {
95 + StringBuilder myResult = new StringBuilder();
96 +
97 + if (person.getFirstName() != null)
98 + {
99 + myResult.append(person.getFirstName());
100 + myResult.append(' ');
101 + }
102 + if ( person.getNickName() != null )
103 + {
104 + myResult.append('\'');
105 + myResult.append(person.getNickName());
106 + myResult.append('\'');
107 + myResult.append(' ');
108 + }
109 + if (person.getLastName() != null)
110 + {
111 + myResult.append(person.getLastName());
112 + }
113 + return myResult.toString();
114 + }
115 + };
116 +
117 + private final String symbol;
118 +
119 + DisplayNameMask(String symbol) {
120 + this.symbol = symbol;
121 + }
122 +
123 + public String getSymbol()
124 + {
125 + return symbol;
126 + }
127 +
128 + public String toString()
129 + {
130 + return symbol;
131 + }
132 +
133 + public abstract String getDisplayName(DisplayNameConfigurable person);
134 +
135 + public abstract String listMask(DisplayNameConfigurable person);
136 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.legrog.entities;
2 +
3 +import org.apache.solr.client.solrj.beans.Field;
4 +import javax.persistence.Id;
5 +import javax.persistence.Lob;
6 +
7 +/**
8 + * Simplified class for searching indexed Accounts
9 + */
10 +public class IndexedAccount {
11 + @Id
12 + @Field
13 + private Integer userId;
14 + @Lob
15 + @Field
16 + private String presentation;
17 +
18 + /**
19 + *
20 + * @param account Account to be simplified as IndexedAccount
21 + */
22 + public IndexedAccount(Account account) {
23 + this.userId = account.getUserId();
24 + this.presentation = account.getPresentation();
25 + }
26 +
27 + public IndexedAccount() {
28 + //no args constructor to make it proxyable
29 + }
30 +
31 + public Integer getUserId() {
32 + return userId;
33 + }
34 +
35 + public void setUserId(Integer userId) {
36 + this.userId = userId;
37 + }
38 +
39 + public String getPresentation() {
40 + return presentation;
41 + }
42 +
43 + public void setPresentation(String presentation) {
44 + this.presentation = presentation;
45 + }
46 +}
1 +package org.legrog.entities;
2 +import org.apache.solr.client.solrj.beans.Field;
3 +import javax.persistence.Id;
4 +import javax.persistence.Lob;
5 +
6 +/**
7 + * Simplified class for indexing and searching validated publishers: content from PublisherVersion with id from Publisher
8 + */
9 +public class IndexedPublisher {
10 + @Id
11 + @Field
12 + private Integer publisherId;
13 + @Field
14 + private String publisherName;
15 + @Lob
16 + @Field
17 + private String publisherHistory;
18 +
19 + /**
20 + * Extracts data needed for indexing from Publisher and its validated PublisherVersion
21 + *
22 + * @param publisher Publisher we want to be indexed
23 + */
24 + public IndexedPublisher(Publisher publisher) {
25 + PublisherVersion publisherVersion = publisher.getValidatedVersion();
26 + this.publisherId = publisher.getPublisherId();
27 + this.publisherName = publisherVersion.getPublisherName();
28 + this.publisherHistory = publisherVersion.getPublisherHistory();
29 + }
30 +
31 + public IndexedPublisher() {
32 + //no args constructor to make it proxyable
33 + }
34 +
35 + public Integer getPublisherId() {
36 + return publisherId;
37 + }
38 +
39 + public String getPublisherName() {
40 + return publisherName;
41 + }
42 +
43 + public String getPublisherHistory() {
44 + return publisherHistory;
45 + }
46 +
47 + public void setPublisherId(Integer publisherId) {
48 + this.publisherId = publisherId;
49 + }
50 +
51 + public void setPublisherName(String publisherName) {
52 + this.publisherName = publisherName;
53 + }
54 +
55 + public void setPublisherHistory(String publisherHistory) {
56 + this.publisherHistory = publisherHistory;
57 + }
58 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.legrog.entities;
2 +
3 +
4 +/**
5 + * Exception when indexing fails, whatever the reason. Has to be dealt with at service level.
6 + */
7 +public class IndexingException extends Exception {
8 + public IndexingException() {
9 + super();
10 + }
11 +
12 + public IndexingException(String message) {
13 + super(message);
14 + }
15 +
16 + public IndexingException(String message, Throwable cause) {
17 + super(message, cause);
18 + }
19 +
20 + public IndexingException(Throwable cause) {
21 + super(cause);
22 + }
23 +
24 + protected IndexingException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
25 + super(message, cause, enableSuppression, writableStackTrace);
26 + }
27 +}
1 +package org.legrog.entities;
2 +
3 +import javax.persistence.*;
4 +import java.util.Set;
5 +
6 +/**
7 + * Persisted entity for a publisher
8 + * Has versions of type PublisherVersion
9 + * May have a validated PublisherVersion among those
10 + * Has access to PublisherAction related to it
11 + */
12 +@Entity
13 +public class Publisher /* extends org.roliste.data.DbLinkableEntity */ {
14 +// TODO L'éventuel usage de Linkable reste à confirmer https://tree.taiga.io/project/jr-utily-grog-v3/us/48
15 +// TODO Attention, en v2 Linkable implique Traceable (journalisable) qui devrait aussi être évalué
16 + @Id
17 + @GeneratedValue(strategy = GenerationType.IDENTITY)
18 + private Integer publisherId;
19 +
20 + @OneToOne
21 + private PublisherVersion validatedVersion;
22 +
23 + @OneToMany(mappedBy = "publisher", fetch = FetchType.EAGER)
24 + private Set<PublisherVersion> versions;
25 +
26 + @OneToMany(mappedBy = "publisher", fetch = FetchType.EAGER)
27 + private Set<PublisherAction> actions;
28 +
29 + public Integer getPublisherId() {
30 + return publisherId;
31 + }
32 +
33 + public void setPublisherId(Integer publisherId) {
34 + this.publisherId = publisherId;
35 + }
36 +
37 + public PublisherVersion getValidatedVersion() {
38 + return validatedVersion;
39 + }
40 +
41 + public void setValidatedVersion(PublisherVersion activeVersion) {
42 + this.validatedVersion = activeVersion;
43 + }
44 +
45 + public Set<PublisherVersion> getVersions() {
46 + return versions;
47 + }
48 +
49 + public void setVersions(Set<PublisherVersion> versions) {
50 + this.versions = versions;
51 + }
52 +
53 + public Set<PublisherAction> getActions() {
54 + return actions;
55 + }
56 +
57 + public void setActions(Set<PublisherAction> actions) {
58 + this.actions = actions;
59 + }
60 +
61 + @Override
62 + public String toString() {
63 + return "PUBLISHER_ID = " + publisherId + ", Validated Version = " + validatedVersion;
64 + }
65 +}
1 +package org.legrog.entities;
2 +
3 +import javax.persistence.*;
4 +import java.sql.Timestamp;
5 +
6 +/**
7 + * Pesisted entity for actions made on PublisherVersion
8 + */
9 +@Entity
10 +public class PublisherAction {
11 + @Id
12 + @GeneratedValue(strategy = GenerationType.IDENTITY)
13 + private Integer publisherActionId;
14 +
15 + @Enumerated
16 + private ActionType actionType;
17 + @ManyToOne
18 + private Account publisherActionActor;
19 + @ManyToOne
20 + private PublisherVersion publisherVersion;
21 +
22 + private Timestamp publisherActionDatetime;
23 +
24 + // Simplified access instead of going through PublisherVersion
25 + @ManyToOne
26 + private Publisher publisher;
27 +
28 + public void setPublisherActionActor(Account publisherActionActor) {
29 + this.publisherActionActor = publisherActionActor;
30 + }
31 +
32 + public void setPublisherActionDatetime(Timestamp publisherActionDatetime) {
33 + this.publisherActionDatetime = publisherActionDatetime;
34 + }
35 +
36 + public void setActionType(ActionType actionType) {
37 + this.actionType = actionType;
38 + }
39 +
40 + public void setPublisherVersion(PublisherVersion publisherVersion) {
41 + this.publisherVersion = publisherVersion;
42 + }
43 +
44 + public void setPublisher(Publisher publisher) {
45 + this.publisher = publisher;
46 + }
47 +
48 + public ActionType getActionType() {
49 + return actionType;
50 + }
51 +
52 + public Account getPublisherActionActor() {
53 + return publisherActionActor;
54 + }
55 +
56 + public PublisherVersion getPublisherVersion() {
57 + return publisherVersion;
58 + }
59 +
60 + public Timestamp getPublisherActionDatetime() {
61 + return publisherActionDatetime;
62 + }
63 +
64 + public Publisher getPublisher() {
65 + return publisher;
66 + }
67 +
68 + public Integer getPublisherActionId() {
69 + return publisherActionId;
70 + }
71 +
72 + public void setPublisherActionId(Integer publisherActionId) {
73 + this.publisherActionId = publisherActionId;
74 + }
75 +
76 + @Override
77 + public String toString() {
78 + return "publisherActionId = " + publisherActionId + ", actionType = " + actionType +
79 + ", publisherActionAuthor = " + publisherActionActor + ", publisherVersion = " + publisherVersion +
80 + ", publisherActionDatetime = " + publisherActionDatetime + ", publisher = " + publisher;
81 + }
82 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.legrog.entities;
2 +
3 +import org.springframework.data.jpa.repository.JpaRepository;
4 +
5 +import java.util.List;
6 +
7 +/**
8 + * Interface for accessing PublisherAction
9 + */
10 +public interface PublisherActionRepository extends JpaRepository<PublisherAction, Integer> {
11 +
12 + /**
13 + * Returns last action of a type for a publisher
14 + *
15 + * @param actionType ActionType requested
16 + * @param publisher Publisher concerned by the action
17 + * @return PublisherAction
18 + */
19 + PublisherAction findFirstByActionTypeAndPublisherOrderByPublisherActionDatetimeDesc(ActionType actionType, Publisher publisher);
20 +
21 + /**
22 + * Returns all actions for a PublisherVersion
23 + *
24 + * @param publisherVersion PublisherVersion concerned by the actions
25 + * @return List<PublisherAction>
26 + */
27 + List<PublisherAction> findByPublisherVersion(PublisherVersion publisherVersion);
28 +}
1 +package org.legrog.entities;
2 +
3 +import org.springframework.data.jpa.repository.JpaRepository;
4 +
5 +import java.util.List;
6 +
7 +public interface PublisherRepository extends JpaRepository<Publisher, Integer> {
8 + List<Publisher> findByValidatedVersionIsNotNull();
9 +}
1 +package org.legrog.entities;
2 +
3 +import java.util.List;
4 +
5 +/**
6 + * Indexing/Search interface for IndexedPublisher
7 + */
8 +public interface PublisherSearchRepository {
9 + /**
10 + * Indexes an IndexedPublisher
11 + *
12 + * @param indexedPublisher IndexedPublisher to be indexed
13 + * @return IndexedPublisher
14 + */
15 + IndexedPublisher save(IndexedPublisher indexedPublisher) throws IndexingException;
16 +
17 + /**
18 + * Searches for IndexedPublishers
19 + *
20 + * @param string String looked for in IndexedPublishers
21 + * @return list of matching IndexedPublishers
22 + */
23 + List<IndexedPublisher> search(String string) throws SearchingException;
24 +
25 + /**
26 + *
27 + * @param inxdexedPublishers IndexedPublishers to reindex
28 + */
29 + public void reindex(List<IndexedPublisher> inxdexedPublishers) throws IndexingException;
30 +}
1 +package org.legrog.entities;
2 +
3 +import org.apache.solr.client.solrj.SolrClient;
4 +import org.apache.solr.client.solrj.SolrQuery;
5 +import org.apache.solr.client.solrj.SolrServerException;
6 +import org.apache.solr.client.solrj.response.QueryResponse;
7 +import org.apache.solr.client.solrj.response.UpdateResponse;
8 +import org.slf4j.Logger;
9 +import org.slf4j.LoggerFactory;
10 +
11 +import javax.enterprise.inject.Default;
12 +import javax.inject.Inject;
13 +import java.io.IOException;
14 +import java.util.ArrayList;
15 +import java.util.List;
16 +
17 +/**
18 + * Implementation of PublisherSearchRepository using SolrJ
19 + */
20 +@Default
21 +public class PublisherSearchRepositorySolrj implements PublisherSearchRepository {
22 + Logger logger = LoggerFactory.getLogger(getClass());
23 +
24 + SolrClient solrClient;
25 +
26 + protected static String collectionName = "publishers";
27 +
28 + @Inject
29 + PublisherSearchRepositorySolrj(SolrClient solrClient) {
30 + this.solrClient = solrClient;
31 + }
32 +
33 + //no args constructor to make it proxyable
34 + PublisherSearchRepositorySolrj() {
35 + }
36 +
37 + @Override
38 + public IndexedPublisher save(IndexedPublisher indexedPublisher) throws IndexingException {
39 + try {
40 + UpdateResponse updateResponse = solrClient.addBean(collectionName, indexedPublisher, 1);
41 + logger.trace("validatePublisherVersion SolrJ UpdateResponse {}", updateResponse);
42 + } catch (IOException ioe) {
43 + throw new IndexingException(ioe);
44 + } catch (SolrServerException sse) {
45 + logger.error("SolrServerException {}", sse);
46 + throw new IndexingException(sse.getRootCause());
47 + }
48 +
49 + return indexedPublisher;
50 + }
51 +
52 + @Override
53 + public List<IndexedPublisher> search(String string) throws SearchingException {
54 + SolrQuery solrQuery = new SolrQuery(string);
55 + QueryResponse queryResponse;
56 + try {
57 + queryResponse = solrClient.query(collectionName, solrQuery);
58 + } catch (IOException ioe) {
59 + throw new SearchingException(ioe);
60 + } catch (SolrServerException sse) {
61 + logger.error("SolrServerException {}", sse);
62 + throw new SearchingException(sse.getRootCause());
63 + }
64 +
65 + if (queryResponse != null) {
66 + return queryResponse.getBeans(IndexedPublisher.class);
67 + } else {
68 + return new ArrayList<>();
69 + }
70 + }
71 +
72 + @Override
73 + public void reindex(List<IndexedPublisher> indexedPublishers) throws IndexingException {
74 + try {
75 + UpdateResponse updateResponse = solrClient.addBeans(collectionName, indexedPublishers);
76 + solrClient.commit(collectionName);
77 + logger.trace("reindex inxdexedPublishers SolrJ UpdateResponse {}", updateResponse);
78 + } catch (IOException ioe) {
79 + throw new IndexingException(ioe);
80 + } catch (SolrServerException sse) {
81 + logger.error("SolrServerException {}", sse);
82 + throw new IndexingException(sse.getRootCause());
83 + }
84 + }
85 +}
1 +package org.legrog.entities;
2 +
3 +import javax.persistence.*;
4 +import java.sql.Timestamp;
5 +
6 +/**
7 + * Persisted entity for a publisher version
8 + * Contains the data
9 + * Postal Address is split according to http://schema.org/PostalAddress
10 + */
11 +@Entity
12 +public class PublisherVersion {
13 + @Id
14 + @GeneratedValue(strategy = GenerationType.IDENTITY)
15 + private Integer publisherVersionId;
16 + @ManyToOne
17 + private Publisher publisher;
18 + private String publisherName;
19 + private String publisherStreetAddress;
20 + private String publisherPostalCode;
21 + private String publisherPostOfficeBoxNumber;
22 + private String publisherAddressRegion;
23 + private String publisherAddressLocality;
24 + @ManyToOne
25 + private Country publisherAddressCountry;
26 + private String publisherTelephone;
27 + private String publisherEmail;
28 + private String publisherURL;
29 + @Lob
30 + private String publisherHistory;
31 + @ManyToOne
32 + private Account publisherVersionCreator;
33 + private Timestamp publisherVersionDatetime;
34 +
35 + public Timestamp getPublisherVersionDatetime() {
36 + return publisherVersionDatetime;
37 + }
38 +
39 + public void setPublisherVersionDatetime(Timestamp publisherVersionDatetime) {
40 + this.publisherVersionDatetime = publisherVersionDatetime;
41 + }
42 +
43 + public String getPublisherHistory() {
44 + return publisherHistory;
45 + }
46 +
47 + public void setPublisherHistory(String publisherHistory) {
48 + this.publisherHistory = publisherHistory;
49 + }
50 +
51 + public String getPublisherStreetAddress() {
52 + return publisherStreetAddress;
53 + }
54 +
55 + public void setPublisherStreetAddress(String publisherStreetAddress) {
56 + this.publisherStreetAddress = publisherStreetAddress;
57 + }
58 +
59 + public String getPublisherPostalCode() {
60 + return publisherPostalCode;
61 + }
62 +
63 + public void setPublisherPostalCode(String publisherPostalCode) {
64 + this.publisherPostalCode = publisherPostalCode;
65 + }
66 +
67 + public String getPublisherPostOfficeBoxNumber() {
68 + return publisherPostOfficeBoxNumber;
69 + }
70 +
71 + public void setPublisherPostOfficeBoxNumber(String publisherPostOfficeBoxNumber) {
72 + this.publisherPostOfficeBoxNumber = publisherPostOfficeBoxNumber;
73 + }
74 +
75 + public String getPublisherAddressRegion() {
76 + return publisherAddressRegion;
77 + }
78 +
79 + public void setPublisherAddressRegion(String publisherAddressRegion) {
80 + this.publisherAddressRegion = publisherAddressRegion;
81 + }
82 +
83 + public String getPublisherAddressLocality() {
84 + return publisherAddressLocality;
85 + }
86 +
87 + public void setPublisherAddressLocality(String publisherAddressLocality) {
88 + this.publisherAddressLocality = publisherAddressLocality;
89 + }
90 +
91 + public String getPublisherTelephone() {
92 + return publisherTelephone;
93 + }
94 +
95 + public void setPublisherTelephone(String publisherTelephone) {
96 + this.publisherTelephone = publisherTelephone;
97 + }
98 +
99 + public String getPublisherEmail() {
100 + return publisherEmail;
101 + }
102 +
103 + public void setPublisherEmail(String publisherEmail) {
104 + this.publisherEmail = publisherEmail;
105 + }
106 +
107 + public String getPublisherURL() {
108 + return publisherURL;
109 + }
110 +
111 + public void setPublisherURL(String publisherURL) {
112 + this.publisherURL = publisherURL;
113 + }
114 +
115 + public Integer getPublisherVersionId() {
116 + return publisherVersionId;
117 + }
118 +
119 + public void setPublisherVersionId(Integer publisherVersionId) {
120 + this.publisherVersionId = publisherVersionId;
121 + }
122 +
123 + public String getPublisherName() {
124 + return publisherName;
125 + }
126 +
127 + public void setPublisherName(String publisherName) {
128 + this.publisherName = publisherName;
129 + }
130 +
131 + public Country getPublisherAddressCountry() {
132 + return publisherAddressCountry;
133 + }
134 +
135 + public void setPublisherAddressCountry(Country publisherAddressCountry) {
136 + this.publisherAddressCountry = publisherAddressCountry;
137 + }
138 +
139 + public Account getPublisherVersionCreator() {
140 + return publisherVersionCreator;
141 + }
142 +
143 + public void setPublisherVersionCreator(Account publisherVersionCreator) {
144 + this.publisherVersionCreator = publisherVersionCreator;
145 + }
146 +
147 + @Override
148 + public String toString() {
149 + return "PUBLISHER_VERSION_ID = " + publisherVersionId + ", Name = " + publisherName + ", St Address = " +
150 + publisherStreetAddress + ", CP = " + publisherPostalCode + ", BP = " + publisherPostOfficeBoxNumber +
151 + ", Region = " + publisherAddressRegion + ", Ville = " + publisherAddressLocality + ", Pays = " +
152 + publisherAddressCountry + ", Telephone = " + publisherTelephone + ", email = " + publisherEmail +
153 + ", URL = " + publisherURL + ", History = " + publisherHistory +
154 + ", Version Author = " + publisherVersionCreator + ", Version DateTime = " + publisherVersionDatetime;
155 + }
156 +
157 + public Publisher getPublisher() {
158 + return publisher;
159 + }
160 +
161 + public void setPublisher(Publisher publisher) {
162 + this.publisher = publisher;
163 + }
164 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.legrog.entities;
2 +
3 +import org.springframework.data.jpa.repository.JpaRepository;
4 +
5 +import java.util.List;
6 +
7 +public interface PublisherVersionRepository extends JpaRepository<PublisherVersion, Integer> {
8 + /**
9 + *
10 + * @param integers list of Ids for the PublisherVersions we're looking for
11 + * @return PublisherVersions looked for
12 + */
13 + List<PublisherVersion> findByPublisherVersionIdIn(List<Integer> integers);
14 +}
1 +package org.legrog.entities;
2 +
3 +/**
4 + * Exception when searching fails, whatever the reason. Has to be dealt with at service level.
5 + */
6 +public class SearchingException extends Exception {
7 + final Throwable rootCause;
8 +
9 + SearchingException(Throwable rootCause) {
10 + this.rootCause = rootCause;
11 + }
12 +
13 + public Throwable getRootCause() {
14 + return rootCause;
15 + }
16 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.legrog.entities;
2 +
3 +import org.apache.solr.client.solrj.SolrClient;
4 +import org.apache.solr.client.solrj.SolrQuery;
5 +import org.apache.solr.client.solrj.SolrServerException;
6 +import org.apache.solr.client.solrj.beans.BindingException;
7 +import org.apache.solr.common.params.SolrParams;
8 +import org.junit.jupiter.api.*;
9 +import org.junit.jupiter.api.extension.ExtendWith;
10 +import org.junit.platform.runner.JUnitPlatform;
11 +import org.junit.runner.RunWith;
12 +import org.legrog.test.MockitoExtension;
13 +import org.mockito.ArgumentCaptor;
14 +import org.mockito.Captor;
15 +import org.mockito.Mock;
16 +import org.mockito.Mockito;
17 +import org.slf4j.Logger;
18 +import org.slf4j.LoggerFactory;
19 +
20 +import java.io.IOException;
21 +
22 +import static org.assertj.core.api.Assertions.assertThat;
23 +import static org.mockito.Mockito.verify;
24 +import static org.mockito.Mockito.when;
25 +
26 +/**
27 + * Classe testant AccountSearchRepositorySolrj
28 + */
29 +@RunWith(JUnitPlatform.class)
30 +@ExtendWith(MockitoExtension.class)
31 +@DisplayName("Indexes and searches with SearchRepository")
32 +
33 +public class AccountSearchRepositorySolrjTest {
34 + Logger logger = LoggerFactory.getLogger(getClass());
35 +
36 + private AccountSearchRepository accountSearchRepository;
37 + private SolrClient solrClient;
38 +
39 + @Captor
40 + ArgumentCaptor<SolrParams> solrParamsArgumentCaptor;
41 +
42 + @BeforeEach
43 + public void setup(@Mock SolrClient solrClient) {
44 + accountSearchRepository = new AccountSearchRepositorySolrj(solrClient);
45 + this.solrClient = solrClient;
46 + }
47 +
48 + @Nested
49 + @DisplayName("search method")
50 + class SearchTests {
51 +
52 + @DisplayName("when repository in IO error, should throw a SearchingException")
53 + @Test
54 + public void searchIOETest() throws IOException, SolrServerException{
55 + when(solrClient.query(Mockito.anyString(), Mockito.any())).thenThrow(new IOException());
56 + Assertions.assertThrows(SearchingException.class, () -> accountSearchRepository.search("a"));
57 + }
58 +
59 + @DisplayName("when repository in SolrServerException, should throw an SearchingException with its root cause")
60 + @Test
61 + public void searchSSETest() throws SolrServerException, IOException {
62 + when(solrClient.query(Mockito.any())).thenThrow(new SolrServerException(new BindingException("BE test 2")));
63 + try {
64 + accountSearchRepository.search("b");
65 + } catch (SearchingException se) {
66 + logger.error("SearchingException {}", se);
67 + assertThat(se.getRootCause().getClass()).isEqualTo(BindingException.class);
68 + }
69 + }
70 +
71 + @DisplayName("when called, it parameter should be embedded in a query sent through SolrClient")
72 + @Test
73 + public void searchParameterTest() throws IOException, SolrServerException {
74 + try {
75 + accountSearchRepository.search("c");
76 + Mockito.verify(solrClient).query(Mockito.anyString(), solrParamsArgumentCaptor.capture());
77 + } catch (SearchingException se) {
78 + logger.error("SearchingException {}", se);
79 + }
80 + SolrQuery solrQuery = (SolrQuery) solrParamsArgumentCaptor.getValue();
81 + assertThat(solrQuery.getQuery()).isEqualTo("c");
82 + }
83 +
84 + }
85 +
86 +
87 +}
1 +package org.legrog.entities;
2 +
3 +import org.apache.solr.client.solrj.SolrClient;
4 +import org.apache.solr.client.solrj.SolrQuery;
5 +import org.apache.solr.client.solrj.SolrServerException;
6 +import org.apache.solr.client.solrj.beans.BindingException;
7 +import org.apache.solr.common.params.SolrParams;
8 +import org.junit.jupiter.api.*;
9 +import org.junit.jupiter.api.extension.ExtendWith;
10 +import org.junit.platform.runner.JUnitPlatform;
11 +import org.junit.runner.RunWith;
12 +import org.legrog.test.MockitoExtension;
13 +import org.mockito.ArgumentCaptor;
14 +import org.mockito.Captor;
15 +import org.mockito.Mock;
16 +import org.mockito.Mockito;
17 +import org.slf4j.Logger;
18 +import org.slf4j.LoggerFactory;
19 +
20 +import java.io.IOException;
21 +
22 +import static org.mockito.Mockito.verify;
23 +import static org.mockito.Mockito.when;
24 +
25 +import static org.assertj.core.api.Assertions.assertThat;
26 +
27 +/**
28 + * Classe testant PublisherSearchRepositorySolrj
29 + */
30 +@RunWith(JUnitPlatform.class)
31 +@ExtendWith(MockitoExtension.class)
32 +@DisplayName("Indexes and searches with SearchRepository")
33 +
34 +public class PublisherSearchRepositorySolrjTest {
35 + Logger logger = LoggerFactory.getLogger(getClass());
36 +
37 + private PublisherSearchRepository publisherSearchRepository;
38 + private SolrClient solrClient;
39 +
40 + @Captor
41 + ArgumentCaptor<SolrParams> solrParamsArgumentCaptor;
42 +
43 + @BeforeEach
44 + public void setup(@Mock SolrClient solrClient) {
45 + publisherSearchRepository = new PublisherSearchRepositorySolrj(solrClient);
46 + this.solrClient = solrClient;
47 + }
48 +
49 + @Nested
50 + @DisplayName("save method")
51 + class SaveTests {
52 +
53 + @Test
54 + @DisplayName("when called with right parameters, should addBean IndexedPublisher with commitWithinMs of 1 to repository")
55 + public void addBeanTest(@Mock IndexedPublisher indexedPublisher) throws IndexingException, SolrServerException, IOException {
56 + publisherSearchRepository.save(indexedPublisher);
57 + verify(solrClient).addBean(PublisherSearchRepositorySolrj.collectionName, indexedPublisher, 1);
58 + }
59 +
60 + @Test
61 + @DisplayName("When repository in IO error, should throw an IndexingException")
62 + public void addBeanIOETest(@Mock IndexedPublisher indexedPublisher) throws SolrServerException, IOException {
63 + when(solrClient.addBean(PublisherSearchRepositorySolrj.collectionName, indexedPublisher, 1)).thenThrow(new IOException());
64 + Assertions.assertThrows(IndexingException.class, () -> publisherSearchRepository.save(indexedPublisher));
65 + }
66 +
67 + @Test
68 + @DisplayName("When repository in SolrServerException, should throw an IndexingException with its root cause")
69 + public void addBeanSSETest(@Mock IndexedPublisher indexedPublisher) throws SolrServerException, IOException{
70 + when(solrClient.addBean(indexedPublisher, 1)).thenThrow(new SolrServerException(new BindingException("BE test")));
71 + try {
72 + publisherSearchRepository.save(indexedPublisher);
73 + } catch (IndexingException ie) {
74 + logger.error("IndexingException {}", ie);
75 + assertThat(ie.getCause().getClass()).isEqualTo(BindingException.class);
76 + }
77 + }
78 + }
79 +
80 + @Nested
81 + @DisplayName("search method")
82 + class SearchTests {
83 +
84 + @DisplayName("when repository in IO error, should throw a SearchingException")
85 + @Test
86 + public void searchIOETest() throws IOException, SolrServerException{
87 + when(solrClient.query(Mockito.anyString(), Mockito.any())).thenThrow(new IOException());
88 + Assertions.assertThrows(SearchingException.class, () -> publisherSearchRepository.search("a"));
89 + }
90 +
91 + @DisplayName("when repository in SolrServerException, should throw an SearchingException with its root cause")
92 + @Test
93 + public void searchSSETest() throws SolrServerException, IOException {
94 + when(solrClient.query(Mockito.any())).thenThrow(new SolrServerException(new BindingException("BE test 2")));
95 + try {
96 + publisherSearchRepository.search("b");
97 + } catch (SearchingException se) {
98 + logger.error("SearchingException {}", se);
99 + assertThat(se.getRootCause().getClass()).isEqualTo(BindingException.class);
100 + }
101 + }
102 +
103 + @DisplayName("when called, it parameter should be embedded in a query sent through SolrClient")
104 + @Test
105 + public void searchParameterTest() throws IOException, SolrServerException {
106 + try {
107 + publisherSearchRepository.search("c");
108 + Mockito.verify(solrClient).query(Mockito.anyString(), solrParamsArgumentCaptor.capture());
109 + } catch (SearchingException se) {
110 + logger.error("SearchingException {}", se);
111 + }
112 + SolrQuery solrQuery = (SolrQuery) solrParamsArgumentCaptor.getValue();
113 + assertThat(solrQuery.getQuery()).isEqualTo("c");
114 + }
115 +
116 + }
117 +
118 +
119 +}
1 +package org.legrog.test;
2 +
3 +/*
4 +
5 +TAKEN FROM JUnit 5 Sample
6 +https://github.com/junit-team/junit5-samples/blob/master/junit5-mockito-extension/src/main/java/com/example/mockito/MockitoExtension.java
7 +
8 +*/
9 +
10 +/*
11 + * Copyright 2015-2016 the original author or authors.
12 + *
13 + * All rights reserved. This program and the accompanying materials are
14 + * made available under the terms of the Eclipse Public License v1.0 which
15 + * accompanies this distribution and is available at
16 + *
17 + * http://www.eclipse.org/legal/epl-v10.html
18 + *
19 + */
20 +
21 +
22 +import static org.mockito.Mockito.mock;
23 +
24 +import java.lang.reflect.Parameter;
25 +
26 +import org.junit.jupiter.api.extension.ExtensionContext;
27 +import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
28 +import org.junit.jupiter.api.extension.ExtensionContext.Store;
29 +import org.junit.jupiter.api.extension.ParameterContext;
30 +import org.junit.jupiter.api.extension.ParameterResolver;
31 +import org.junit.jupiter.api.extension.TestInstancePostProcessor;
32 +import org.mockito.Mock;
33 +import org.mockito.MockitoAnnotations;
34 +
35 +/**
36 + * {@code MockitoExtension} showcases the {@link TestInstancePostProcessor}
37 + * and {@link ParameterResolver} extension APIs of JUnit 5 by providing
38 + * dependency injection support at the field level and at the method parameter
39 + * level via Mockito 2.x's {@link Mock @Mock} annotation.
40 + */
41 +public class MockitoExtension implements TestInstancePostProcessor, ParameterResolver {
42 +
43 + @Override
44 + public void postProcessTestInstance(Object testInstance, ExtensionContext context) {
45 + MockitoAnnotations.initMocks(testInstance);
46 + }
47 +
48 + @Override
49 + public boolean supports(ParameterContext parameterContext, ExtensionContext extensionContext) {
50 + return parameterContext.getParameter().isAnnotationPresent(Mock.class);
51 + }
52 +
53 + @Override
54 + public Object resolve(ParameterContext parameterContext, ExtensionContext extensionContext) {
55 + return getMock(parameterContext.getParameter(), extensionContext);
56 + }
57 +
58 + private Object getMock(Parameter parameter, ExtensionContext extensionContext) {
59 + Class<?> mockType = parameter.getType();
60 + Store mocks = extensionContext.getStore(Namespace.create(MockitoExtension.class, mockType));
61 + String mockName = getMockName(parameter);
62 +
63 + if (mockName != null) {
64 + return mocks.getOrComputeIfAbsent(mockName, key -> mock(mockType, mockName));
65 + } else {
66 + return mocks.getOrComputeIfAbsent(mockType.getCanonicalName(), key -> mock(mockType));
67 + }
68 + }
69 +
70 + private String getMockName(Parameter parameter) {
71 + String explicitMockName = parameter.getAnnotation(Mock.class).name().trim();
72 + if (!explicitMockName.isEmpty()) {
73 + return explicitMockName;
74 + } else if (parameter.isNamePresent()) {
75 + return parameter.getName();
76 + }
77 + return null;
78 + }
79 +
80 +}
81 +
1 +package org.legrog.util;
2 +// Code copied from org.h2.server.web.WebSession
3 +/*
4 + * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
5 + * and the EPL 1.0 (http://h2database.com/html/license.html).
6 + * Initial Developer: H2 Group
7 + */
8 +///package org.h2.server.web;
9 +
10 + import java.sql.Connection;
11 + import java.sql.DatabaseMetaData;
12 + import java.sql.ResultSet;
13 + import java.sql.SQLException;
14 + import java.sql.Statement;
15 + import java.sql.Timestamp;
16 + import java.util.ArrayList;
17 + import java.util.HashMap;
18 + import java.util.Locale;
19 +
20 + import org.h2.bnf.Bnf;
21 + import org.h2.bnf.context.DbContents;
22 + import org.h2.bnf.context.DbContextRule;
23 + import org.h2.message.DbException;
24 + import org.h2.util.New;
25 +
26 +/**
27 + * The web session keeps all data of a user session.
28 + * This class is used by the H2 Console.
29 + */
30 +class WebSession {
31 +
32 + private static final int MAX_HISTORY = 1000;
33 +
34 + /**
35 + * The last time this client sent a request.
36 + */
37 + long lastAccess;
38 +
39 + /**
40 + * The session attribute map.
41 + */
42 + final HashMap<String, Object> map = New.hashMap();
43 +
44 + /**
45 + * The current locale.
46 + */
47 + Locale locale;
48 +
49 + /**
50 + * The currently executing statement.
51 + */
52 + Statement executingStatement;
53 +
54 + /**
55 + * The current updatable result set.
56 + */
57 + ResultSet result;
58 +
59 + private final WebServer server;
60 +
61 + private final ArrayList<String> commandHistory;
62 +
63 + private Connection conn;
64 + private DatabaseMetaData meta;
65 + private DbContents contents = new DbContents();
66 + private Bnf bnf;
67 + private boolean shutdownServerOnDisconnect;
68 +
69 + WebSession(WebServer server) {
70 + this.server = server;
71 + // This must be stored in the session rather than in the server.
72 + // Otherwise, one client could allow
73 + // saving history for others (insecure).
74 + this.commandHistory = server.getCommandHistoryList();
75 + }
76 +
77 + /**
78 + * Put an attribute value in the map.
79 + *
80 + * @param key the key
81 + * @param value the new value
82 + */
83 + void put(String key, Object value) {
84 + map.put(key, value);
85 + }
86 +
87 + /**
88 + * Get the value for the given key.
89 + *
90 + * @param key the key
91 + * @return the value
92 + */
93 + Object get(String key) {
94 + if ("sessions".equals(key)) {
95 + return server.getSessions();
96 + }
97 + return map.get(key);
98 + }
99 +
100 + /**
101 + * Remove a session attribute from the map.
102 + *
103 + * @param key the key
104 + */
105 + void remove(String key) {
106 + map.remove(key);
107 + }
108 +
109 + /**
110 + * Get the BNF object.
111 + *
112 + * @return the BNF object
113 + */
114 + Bnf getBnf() {
115 + return bnf;
116 + }
117 +
118 + /**
119 + * Load the SQL grammar BNF.
120 + */
121 + void loadBnf() {
122 + try {
123 + Bnf newBnf = Bnf.getInstance(null);
124 + DbContextRule columnRule =
125 + new DbContextRule(contents, DbContextRule.COLUMN);
126 + DbContextRule newAliasRule =
127 + new DbContextRule(contents, DbContextRule.NEW_TABLE_ALIAS);
128 + DbContextRule aliasRule =
129 + new DbContextRule(contents, DbContextRule.TABLE_ALIAS);
130 + DbContextRule tableRule =
131 + new DbContextRule(contents, DbContextRule.TABLE);
132 + DbContextRule schemaRule =
133 + new DbContextRule(contents, DbContextRule.SCHEMA);
134 + DbContextRule columnAliasRule =
135 + new DbContextRule(contents, DbContextRule.COLUMN_ALIAS);
136 + DbContextRule procedure =
137 + new DbContextRule(contents, DbContextRule.PROCEDURE);
138 + newBnf.updateTopic("procedure", procedure);
139 + newBnf.updateTopic("column_name", columnRule);
140 + newBnf.updateTopic("new_table_alias", newAliasRule);
141 + newBnf.updateTopic("table_alias", aliasRule);
142 + newBnf.updateTopic("column_alias", columnAliasRule);
143 + newBnf.updateTopic("table_name", tableRule);
144 + newBnf.updateTopic("schema_name", schemaRule);
145 + newBnf.linkStatements();
146 + bnf = newBnf;
147 + } catch (Exception e) {
148 + // ok we don't have the bnf
149 + server.traceError(e);
150 + }
151 + }
152 +
153 + /**
154 + * Get the SQL statement from history.
155 + *
156 + * @param id the history id
157 + * @return the SQL statement
158 + */
159 + String getCommand(int id) {
160 + return commandHistory.get(id);
161 + }
162 +
163 + /**
164 + * Add a SQL statement to the history.
165 + *
166 + * @param sql the SQL statement
167 + */
168 + void addCommand(String sql) {
169 + if (sql == null) {
170 + return;
171 + }
172 + sql = sql.trim();
173 + if (sql.length() == 0) {
174 + return;
175 + }
176 + if (commandHistory.size() > MAX_HISTORY) {
177 + commandHistory.remove(0);
178 + }
179 + int idx = commandHistory.indexOf(sql);
180 + if (idx >= 0) {
181 + commandHistory.remove(idx);
182 + }
183 + commandHistory.add(sql);
184 + if (server.isCommandHistoryAllowed()) {
185 + server.saveCommandHistoryList(commandHistory);
186 + }
187 + }
188 +
189 + /**
190 + * Get the list of SQL statements in the history.
191 + *
192 + * @return the commands
193 + */
194 + ArrayList<String> getCommandHistory() {
195 + return commandHistory;
196 + }
197 +
198 + /**
199 + * Update session meta data information and get the information in a map.
200 + *
201 + * @return a map containing the session meta data
202 + */
203 + HashMap<String, Object> getInfo() {
204 + HashMap<String, Object> m = New.hashMap();
205 + m.putAll(map);
206 + m.put("lastAccess", new Timestamp(lastAccess).toString());
207 + try {
208 + m.put("url", conn == null ?
209 + "${text.admin.notConnected}" : conn.getMetaData().getURL());
210 + m.put("user", conn == null ?
211 + "-" : conn.getMetaData().getUserName());
212 + m.put("lastQuery", commandHistory.size() == 0 ?
213 + "" : commandHistory.get(0));
214 + m.put("executing", executingStatement == null ?
215 + "${text.admin.no}" : "${text.admin.yes}");
216 + } catch (SQLException e) {
217 + DbException.traceThrowable(e);
218 + }
219 + return m;
220 + }
221 +
222 + void setConnection(Connection conn) throws SQLException {
223 + this.conn = conn;
224 + if (conn == null) {
225 + meta = null;
226 + } else {
227 + meta = conn.getMetaData();
228 + }
229 + contents = new DbContents();
230 + }
231 +
232 + DatabaseMetaData getMetaData() {
233 + return meta;
234 + }
235 +
236 + Connection getConnection() {
237 + return conn;
238 + }
239 +
240 + DbContents getContents() {
241 + return contents;
242 + }
243 +
244 + /**
245 + * Shutdown the server when disconnecting.
246 + */
247 + void setShutdownServerOnDisconnect() {
248 + this.shutdownServerOnDisconnect = true;
249 + }
250 +
251 + boolean getShutdownServerOnDisconnect() {
252 + return shutdownServerOnDisconnect;
253 + }
254 +
255 + /**
256 + * Close the connection and stop the statement if one is currently
257 + * executing.
258 + */
259 + void close() {
260 + if (executingStatement != null) {
261 + try {
262 + executingStatement.cancel();
263 + } catch (Exception e) {
264 + // ignore
265 + }
266 + }
267 + if (conn != null) {
268 + try {
269 + conn.close();
270 + } catch (Exception e) {
271 + // ignore
272 + }
273 + }
274 +
275 + }
276 +
277 +}
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<beans xmlns="http://java.sun.com/xml/ns/javaee"
3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd" />
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
5 xmlns:jsf="http://xmlns.jcp.org/jsf" 5 xmlns:jsf="http://xmlns.jcp.org/jsf"
6 xmlns:ui="http://xmlns.jcp.org/jsf/facelets"> 6 xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
7 <body> 7 <body>
8 -<ui:include src="/org/legrog/web/navigation.xhtml" /> 8 +<ui:include src="/navigation.xhtml" />
9 </body> 9 </body>
10 </html> 10 </html>
...\ No newline at end of file ...\ No newline at end of file
......
1 +package org.legrog.web.xyz;
2 +
3 +import org.junit.jupiter.api.BeforeEach;
4 +import org.junit.jupiter.api.DisplayName;
5 +import org.junit.jupiter.api.Nested;
6 +import org.junit.jupiter.api.Test;
7 +import org.junit.jupiter.api.extension.ExtendWith;
8 +import org.junit.platform.runner.JUnitPlatform;
9 +import org.junit.runner.RunWith;
10 +import org.legrog.entities.Account;
11 +import org.legrog.entities.PublisherVersion;
12 +import org.legrog.entities.SearchingException;
13 +import org.legrog.test.MockitoExtension;
14 +import org.legrog.web.account.AccountService;
15 +import org.legrog.web.publisher.PublisherService;
16 +import org.mockito.Mock;
17 +import org.mockito.Mockito;
18 +
19 +import java.util.ArrayList;
20 +import java.util.List;
21 +
22 +import static org.assertj.core.api.Assertions.assertThat;
23 +import static org.mockito.Mockito.when;
24 +
25 +/**
26 + * Classe testant SearchView
27 + */
28 +@RunWith(JUnitPlatform.class)
29 +@ExtendWith(MockitoExtension.class)
30 +@DisplayName("Searches for an indexed publisher")
31 +public class SearchViewTest {
32 +
33 + private SearchView searchView;
34 + private PublisherService publisherService;
35 + private AccountService accountService;
36 +
37 + @BeforeEach
38 + public void setUp(@Mock PublisherService publisherService, @Mock AccountService accountService) {
39 + this.publisherService = publisherService;
40 + this.accountService = accountService;
41 + this.searchView = new SearchView(publisherService, accountService);
42 + }
43 +
44 + @Nested
45 + @DisplayName("search method")
46 + class SearchTests {
47 +
48 + @Test
49 + @DisplayName("when called, should delegate search to PublisherService and AccountService with same string")
50 + public void searchUsesPublisherService(@Mock PublisherService publisherService, @Mock AccountService accountService) throws SearchingException{
51 + searchView.setSearchString("1");
52 + searchView.search();
53 + Mockito.verify(publisherService).search("1");
54 + Mockito.verify(accountService).search("1");
55 + }
56 +
57 + @Test
58 + @DisplayName("when called, should return the answer it gets from PublisherService")
59 + public void searchReturnsDataFromPublisherService(@Mock PublisherService publisherService) throws SearchingException {
60 + List<PublisherVersion> publisherVersionList = new ArrayList<>();
61 + when(publisherService.search("2")).thenReturn(publisherVersionList);
62 + searchView.setSearchString("2");
63 + searchView.search();
64 + assertThat(searchView.getPublisherVersions()).isEqualTo(publisherVersionList);
65 + }
66 +
67 + @Test
68 + @DisplayName("when called, should return the answer it gets from AccountService")
69 + public void searchReturnsDataFromAccountService(@Mock AccountService accountService) throws SearchingException {
70 + List<Account> publisherVersionList = new ArrayList<>();
71 + when(accountService.search("3")).thenReturn(publisherVersionList);
72 + searchView.setSearchString("3");
73 + searchView.search();
74 + assertThat(searchView.getPublisherVersions()).isEqualTo(publisherVersionList);
75 + }
76 +
77 + }
78 +}
This diff is collapsed. Click to expand it.