Revision 47801
Added by Claudio Atzori over 7 years ago
modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2/src/main/java/eu/dnetlib/enabling/is/sn/AsynchronousNotificationSenderImpl.java | ||
---|---|---|
1 |
package eu.dnetlib.enabling.is.sn; |
|
2 |
|
|
3 |
import java.util.concurrent.BlockingQueue; |
|
4 |
import java.util.concurrent.LinkedBlockingQueue; |
|
5 |
|
|
6 |
import javax.xml.ws.wsaddressing.W3CEndpointReference; |
|
7 |
|
|
8 |
import org.apache.commons.logging.Log; |
|
9 |
import org.apache.commons.logging.LogFactory; |
|
10 |
|
|
11 |
/** |
|
12 |
* Asynchronous but in-order delivery of notifications. |
|
13 |
* |
|
14 |
* @author marko |
|
15 |
* |
|
16 |
*/ |
|
17 |
public class AsynchronousNotificationSenderImpl extends AbstractNotificationSender implements Runnable { // NOPMD |
|
18 |
/** |
|
19 |
* logger. |
|
20 |
*/ |
|
21 |
private static final Log log = LogFactory.getLog(AsynchronousNotificationSenderImpl.class); // NOPMD by marko on 11/24/08 5:02 PM |
|
22 |
|
|
23 |
/** |
|
24 |
* Encapsulates an notification job. |
|
25 |
* |
|
26 |
* @author marko |
|
27 |
* |
|
28 |
*/ |
|
29 |
class NotificationJob { |
|
30 |
/** |
|
31 |
* notification destination. |
|
32 |
*/ |
|
33 |
private final transient W3CEndpointReference destination; |
|
34 |
|
|
35 |
/** |
|
36 |
* notification message. |
|
37 |
*/ |
|
38 |
private final transient NotificationMessage message; |
|
39 |
|
|
40 |
/** |
|
41 |
* construct a new notification job. |
|
42 |
* |
|
43 |
* @param destination destination |
|
44 |
* @param message message |
|
45 |
*/ |
|
46 |
public NotificationJob(final W3CEndpointReference destination, final NotificationMessage message) { |
|
47 |
super(); |
|
48 |
this.destination = destination; |
|
49 |
this.message = message; |
|
50 |
} |
|
51 |
|
|
52 |
public W3CEndpointReference getDestination() { |
|
53 |
return destination; |
|
54 |
} |
|
55 |
|
|
56 |
public NotificationMessage getMessage() { |
|
57 |
return message; |
|
58 |
} |
|
59 |
|
|
60 |
} |
|
61 |
|
|
62 |
/** |
|
63 |
* job queue. |
|
64 |
*/ |
|
65 |
private BlockingQueue<NotificationJob> jobQueue = new LinkedBlockingQueue<NotificationJob>(); |
|
66 |
|
|
67 |
/** |
|
68 |
* {@inheritDoc} |
|
69 |
* |
|
70 |
* @see eu.dnetlib.enabling.is.sn.NotificationSender#send(javax.xml.ws.wsaddressing.W3CEndpointReference, |
|
71 |
* eu.dnetlib.enabling.is.sn.NotificationMessage) |
|
72 |
*/ |
|
73 |
@Override |
|
74 |
public void send(final W3CEndpointReference destination, final NotificationMessage message) { |
|
75 |
log.debug("queuing asynchronous notification"); |
|
76 |
try { |
|
77 |
jobQueue.put(new NotificationJob(destination, message)); |
|
78 |
} catch (InterruptedException e) { |
|
79 |
log.warn("possibly lost notification", e); |
|
80 |
} |
|
81 |
} |
|
82 |
|
|
83 |
/** |
|
84 |
* start this notification sender (called by spring lifecycle). |
|
85 |
*/ |
|
86 |
void start() { |
|
87 |
new Thread(this).start(); // NOPMD |
|
88 |
} |
|
89 |
|
|
90 |
/** |
|
91 |
* {@inheritDoc} |
|
92 |
* @see java.lang.Runnable#run() |
|
93 |
*/ |
|
94 |
@Override |
|
95 |
public void run() { |
|
96 |
while (true) { |
|
97 |
try { |
|
98 |
final NotificationJob job = jobQueue.take(); |
|
99 |
|
|
100 |
try { |
|
101 |
getInvoker().send(job.getDestination(), job.getMessage(), 0); |
|
102 |
} catch (javax.xml.ws.soap.SOAPFaultException t) { |
|
103 |
log.fatal("error sending notification to " + job.getDestination().toString(), t); |
|
104 |
} |
|
105 |
} catch (InterruptedException e) { |
|
106 |
log.warn("possibly lost notification", e); |
|
107 |
} |
|
108 |
} |
|
109 |
} |
|
110 |
|
|
111 |
public BlockingQueue<NotificationJob> getJobQueue() { |
|
112 |
return jobQueue; |
|
113 |
} |
|
114 |
|
|
115 |
public void setJobQueue(final BlockingQueue<NotificationJob> jobQueue) { |
|
116 |
this.jobQueue = jobQueue; |
|
117 |
} |
|
118 |
|
|
119 |
} |
modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2/src/main/java/eu/dnetlib/enabling/is/sn/NotificationTriggerImpl.java | ||
---|---|---|
1 |
package eu.dnetlib.enabling.is.sn; |
|
2 |
|
|
3 |
import javax.xml.xpath.XPathExpressionException; |
|
4 |
|
|
5 |
import org.apache.commons.logging.Log; |
|
6 |
import org.apache.commons.logging.LogFactory; |
|
7 |
import org.w3c.dom.Document; |
|
8 |
|
|
9 |
import eu.dnetlib.enabling.is.sn.resourcestate.ResourceStateNotificationDetector; |
|
10 |
import eu.dnetlib.enabling.tools.DOMOpaqueResource; |
|
11 |
import eu.dnetlib.enabling.tools.OpaqueResource; |
|
12 |
import eu.dnetlib.xml.database.LoggingTrigger; |
|
13 |
|
|
14 |
/** |
|
15 |
* This trigger generates notification events for the subscription notification layer. |
|
16 |
* |
|
17 |
* @author marko |
|
18 |
* |
|
19 |
*/ |
|
20 |
public class NotificationTriggerImpl extends LoggingTrigger { |
|
21 |
/** |
|
22 |
* logger. |
|
23 |
*/ |
|
24 |
private static final Log log = LogFactory.getLog(NotificationTriggerImpl.class); // NOPMD by marko on 11/24/08 5:02 PM |
|
25 |
|
|
26 |
/** |
|
27 |
* notification detector to notify on events. |
|
28 |
*/ |
|
29 |
private ResourceStateNotificationDetector<OpaqueResource> detector; |
|
30 |
|
|
31 |
/** |
|
32 |
* {@inheritDoc} |
|
33 |
* @see eu.dnetlib.xml.database.LoggingTrigger#created(java.lang.String, java.lang.String, org.w3c.dom.Document) |
|
34 |
*/ |
|
35 |
@Override |
|
36 |
public void created(final String file, final String collection, final Document newDoc) { |
|
37 |
super.created(file, collection, newDoc); |
|
38 |
try { |
|
39 |
getDetector().resourceCreated(new DOMOpaqueResource(newDoc)); |
|
40 |
} catch (XPathExpressionException e) { |
|
41 |
log.fatal("cannot detect notification because of xpath error; notification possibly missed", e); |
|
42 |
} |
|
43 |
} |
|
44 |
|
|
45 |
/** |
|
46 |
* {@inheritDoc} |
|
47 |
* @see eu.dnetlib.xml.database.LoggingTrigger#deleted(java.lang.String, java.lang.String, org.w3c.dom.Document) |
|
48 |
*/ |
|
49 |
@Override |
|
50 |
public void deleted(final String file, final String collection, final Document oldDoc) { |
|
51 |
super.deleted(file, collection, oldDoc); |
|
52 |
try { |
|
53 |
getDetector().resourceDeleted(new DOMOpaqueResource(oldDoc)); |
|
54 |
} catch (XPathExpressionException e) { |
|
55 |
log.fatal("cannot detect notification because of xpath error; notification possibly missed", e); |
|
56 |
} |
|
57 |
} |
|
58 |
|
|
59 |
/** |
|
60 |
* {@inheritDoc} |
|
61 |
* @see eu.dnetlib.xml.database.LoggingTrigger#updated(java.lang.String, java.lang.String, org.w3c.dom.Document, org.w3c.dom.Document) |
|
62 |
*/ |
|
63 |
@Override |
|
64 |
public void updated(final String file, final String collection, final Document oldDoc, final Document newDoc) { |
|
65 |
super.updated(file, collection, oldDoc, newDoc); |
|
66 |
try { |
|
67 |
getDetector().resourceUpdated(new DOMOpaqueResource(oldDoc), new DOMOpaqueResource(newDoc)); |
|
68 |
} catch (XPathExpressionException e) { |
|
69 |
log.fatal("cannot detect notification because of xpath error; notification possibly missed", e); |
|
70 |
} |
|
71 |
} |
|
72 |
|
|
73 |
public ResourceStateNotificationDetector<OpaqueResource> getDetector() { |
|
74 |
return detector; |
|
75 |
} |
|
76 |
|
|
77 |
public void setDetector(final ResourceStateNotificationDetector<OpaqueResource> detector) { |
|
78 |
this.detector = detector; |
|
79 |
} |
|
80 |
} |
modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2/src/main/java/eu/dnetlib/enabling/is/registry/schema/PermissiveOpaqueResourceValidatorImpl.java | ||
---|---|---|
1 |
package eu.dnetlib.enabling.is.registry.schema; |
|
2 |
|
|
3 |
import org.apache.commons.logging.Log; |
|
4 |
import org.apache.commons.logging.LogFactory; |
|
5 |
|
|
6 |
import eu.dnetlib.enabling.tools.OpaqueResource; |
|
7 |
|
|
8 |
/** |
|
9 |
* Unlike the OpaqueResourceValidatorImpl, this implementation only logs an error but accepts every resource as valid. |
|
10 |
* |
|
11 |
* Use only during testing/development! |
|
12 |
* |
|
13 |
* @author marko |
|
14 |
* |
|
15 |
*/ |
|
16 |
public class PermissiveOpaqueResourceValidatorImpl extends OpaqueResourceValidatorImpl { |
|
17 |
/** |
|
18 |
* logger. |
|
19 |
*/ |
|
20 |
private static final Log log = LogFactory.getLog(PermissiveOpaqueResourceValidatorImpl.class); // NOPMD by marko on 11/24/08 5:02 PM |
|
21 |
|
|
22 |
/** |
|
23 |
* {@inheritDoc} |
|
24 |
* |
|
25 |
* @see eu.dnetlib.enabling.is.registry.schema.OpaqueResourceValidatorImpl#validate(eu.dnetlib.enabling.tools.OpaqueResource) |
|
26 |
*/ |
|
27 |
@Override |
|
28 |
public void validate(final OpaqueResource resource) throws ValidationException { |
|
29 |
try { |
|
30 |
super.validate(resource); |
|
31 |
} catch (ValidationException e) { |
|
32 |
log.fatal("validation error, continuing (permissive mode)", e); |
|
33 |
} |
|
34 |
} |
|
35 |
|
|
36 |
} |
modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2/src/main/java/eu/dnetlib/enabling/is/sn/MemoryNotificationInvocationLogger.java | ||
---|---|---|
1 |
package eu.dnetlib.enabling.is.sn; |
|
2 |
|
|
3 |
import java.util.Collection; |
|
4 |
import java.util.Date; |
|
5 |
import java.util.concurrent.ConcurrentLinkedQueue; |
|
6 |
|
|
7 |
import javax.xml.ws.wsaddressing.W3CEndpointReference; |
|
8 |
|
|
9 |
/** |
|
10 |
* In memory implementation of a notification invocation logger. |
|
11 |
* |
|
12 |
* @author marko |
|
13 |
* |
|
14 |
*/ |
|
15 |
public class MemoryNotificationInvocationLogger implements NotificationInvocationLogger { |
|
16 |
|
|
17 |
/** |
|
18 |
* default log size. |
|
19 |
*/ |
|
20 |
private static final int DEFAULT_SIZE = 100; |
|
21 |
|
|
22 |
/** |
|
23 |
* Entry. |
|
24 |
* |
|
25 |
* @author marko |
|
26 |
* |
|
27 |
*/ |
|
28 |
public class MemoryEntry implements Entry { |
|
29 |
|
|
30 |
/** |
|
31 |
* logged message. |
|
32 |
*/ |
|
33 |
private NotificationMessage message; |
|
34 |
|
|
35 |
/** |
|
36 |
* message status. |
|
37 |
*/ |
|
38 |
private Status status = Status.Queued; |
|
39 |
|
|
40 |
/** |
|
41 |
* saved exception in case of Failed state. |
|
42 |
*/ |
|
43 |
private Throwable exception; |
|
44 |
|
|
45 |
/** |
|
46 |
* destination. |
|
47 |
*/ |
|
48 |
private W3CEndpointReference destinationEpr; |
|
49 |
|
|
50 |
/** |
|
51 |
* start date time. |
|
52 |
*/ |
|
53 |
private Date start; |
|
54 |
|
|
55 |
/** |
|
56 |
* finish date time. |
|
57 |
*/ |
|
58 |
private Date finish; |
|
59 |
|
|
60 |
/** |
|
61 |
* construct a new message. |
|
62 |
* |
|
63 |
* @param endpointReference |
|
64 |
* destination |
|
65 |
* |
|
66 |
* @param message |
|
67 |
* message |
|
68 |
*/ |
|
69 |
public MemoryEntry(final W3CEndpointReference endpointReference, final NotificationMessage message) { |
|
70 |
this.destinationEpr = endpointReference; |
|
71 |
this.message = message; |
|
72 |
this.start = new Date(); |
|
73 |
} |
|
74 |
|
|
75 |
/** |
|
76 |
* {@inheritDoc} |
|
77 |
* |
|
78 |
* @see eu.dnetlib.enabling.is.sn.NotificationInvocationLogger.Entry#ongoing() |
|
79 |
*/ |
|
80 |
@Override |
|
81 |
public void ongoing() { |
|
82 |
status = Status.Ongoing; |
|
83 |
} |
|
84 |
|
|
85 |
/** |
|
86 |
* {@inheritDoc} |
|
87 |
* |
|
88 |
* @see eu.dnetlib.enabling.is.sn.NotificationInvocationLogger.Entry#failure(java.lang.Throwable) |
|
89 |
*/ |
|
90 |
@Override |
|
91 |
public void failure(final Throwable exc) { |
|
92 |
status = Status.Failed; |
|
93 |
this.exception = exc; |
|
94 |
commit(); |
|
95 |
} |
|
96 |
|
|
97 |
/** |
|
98 |
* {@inheritDoc} |
|
99 |
* |
|
100 |
* @see eu.dnetlib.enabling.is.sn.NotificationInvocationLogger.Entry#success() |
|
101 |
*/ |
|
102 |
@Override |
|
103 |
public void success() { |
|
104 |
status = Status.Succeeded; |
|
105 |
commit(); |
|
106 |
} |
|
107 |
|
|
108 |
/** |
|
109 |
* finalize log entry. |
|
110 |
*/ |
|
111 |
protected void commit() { |
|
112 |
this.finish = new Date(); |
|
113 |
} |
|
114 |
|
|
115 |
@Override |
|
116 |
public NotificationMessage getMessage() { |
|
117 |
return message; |
|
118 |
} |
|
119 |
|
|
120 |
public void setMessage(final NotificationMessage message) { |
|
121 |
this.message = message; |
|
122 |
} |
|
123 |
|
|
124 |
@Override |
|
125 |
public Throwable getException() { |
|
126 |
return exception; |
|
127 |
} |
|
128 |
|
|
129 |
public void setException(final Throwable exception) { |
|
130 |
this.exception = exception; |
|
131 |
} |
|
132 |
|
|
133 |
@Override |
|
134 |
public Status getStatus() { |
|
135 |
return status; |
|
136 |
} |
|
137 |
|
|
138 |
public void setStatus(final Status status) { |
|
139 |
this.status = status; |
|
140 |
} |
|
141 |
|
|
142 |
public W3CEndpointReference getDestinationEpr() { |
|
143 |
return destinationEpr; |
|
144 |
} |
|
145 |
|
|
146 |
public void setDestinationEpr(final W3CEndpointReference destinationEpr) { |
|
147 |
this.destinationEpr = destinationEpr; |
|
148 |
} |
|
149 |
|
|
150 |
@Override |
|
151 |
public String getDestination() { |
|
152 |
return EPRUtil.getAddress(destinationEpr); |
|
153 |
} |
|
154 |
|
|
155 |
/** |
|
156 |
* {@inheritDoc} |
|
157 |
* |
|
158 |
* @see eu.dnetlib.enabling.is.sn.NotificationInvocationLogger.Entry#getErrorMessage() |
|
159 |
*/ |
|
160 |
@Override |
|
161 |
public String getErrorMessage() { |
|
162 |
if (getException() == null) |
|
163 |
return ""; |
|
164 |
return getException().getMessage(); |
|
165 |
} |
|
166 |
|
|
167 |
@Override |
|
168 |
public Date getStart() { |
|
169 |
return start; |
|
170 |
} |
|
171 |
|
|
172 |
public void setStart(final Date start) { |
|
173 |
this.start = start; |
|
174 |
} |
|
175 |
|
|
176 |
@Override |
|
177 |
public Date getFinish() { |
|
178 |
return finish; |
|
179 |
} |
|
180 |
|
|
181 |
public void setFinish(final Date finish) { |
|
182 |
this.finish = finish; |
|
183 |
} |
|
184 |
|
|
185 |
/** |
|
186 |
* {@inheritDoc} |
|
187 |
* @see eu.dnetlib.enabling.is.sn.NotificationInvocationLogger.Entry#getDuration() |
|
188 |
*/ |
|
189 |
@Override |
|
190 |
public String getDuration() { |
|
191 |
if (finish == null || start == null) |
|
192 |
return "-"; |
|
193 |
return (finish.getTime() - start.getTime()) + " ms"; |
|
194 |
} |
|
195 |
} |
|
196 |
|
|
197 |
/** |
|
198 |
* the actual log storage. |
|
199 |
*/ |
|
200 |
private ConcurrentLinkedQueue<Entry> queue = new ConcurrentLinkedQueue<Entry>(); |
|
201 |
|
|
202 |
/** |
|
203 |
* max log size. |
|
204 |
*/ |
|
205 |
private int size = DEFAULT_SIZE; |
|
206 |
|
|
207 |
/** |
|
208 |
* {@inheritDoc} |
|
209 |
* |
|
210 |
* @see eu.dnetlib.enabling.is.sn.NotificationInvocationLogger#startLogging(eu.dnetlib.enabling.is.sn.NotificationMessage) |
|
211 |
*/ |
|
212 |
@Override |
|
213 |
public Entry startLogging(final W3CEndpointReference dest, final NotificationMessage message) { |
|
214 |
final Entry entry = createLoggingEntry(dest, message); |
|
215 |
queue.add(entry); |
|
216 |
ensureQueueLength(); |
|
217 |
return entry; |
|
218 |
} |
|
219 |
|
|
220 |
/** |
|
221 |
* ensure that the queue doesn't grow beyond size. |
|
222 |
*/ |
|
223 |
private void ensureQueueLength() { |
|
224 |
if (queue.size() > size) |
|
225 |
queue.poll(); |
|
226 |
} |
|
227 |
|
|
228 |
/** |
|
229 |
* create a new memory log object. |
|
230 |
* |
|
231 |
* @param dest |
|
232 |
* destination |
|
233 |
* |
|
234 |
* @param message |
|
235 |
* message to be logged |
|
236 |
* @return new entry instance |
|
237 |
*/ |
|
238 |
protected Entry createLoggingEntry(final W3CEndpointReference dest, final NotificationMessage message) { |
|
239 |
return new MemoryEntry(dest, message); |
|
240 |
} |
|
241 |
|
|
242 |
public ConcurrentLinkedQueue<Entry> getQueue() { |
|
243 |
return queue; |
|
244 |
} |
|
245 |
|
|
246 |
public void setQueue(final ConcurrentLinkedQueue<Entry> queue) { |
|
247 |
this.queue = queue; |
|
248 |
} |
|
249 |
|
|
250 |
public int getSize() { |
|
251 |
return size; |
|
252 |
} |
|
253 |
|
|
254 |
public void setSize(final int size) { |
|
255 |
this.size = size; |
|
256 |
} |
|
257 |
|
|
258 |
@Override |
|
259 |
public Collection<Entry> getEntries() { |
|
260 |
return getQueue(); |
|
261 |
} |
|
262 |
|
|
263 |
} |
modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2/pom.xml | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
|
3 |
<parent> |
|
4 |
<groupId>eu.dnetlib</groupId> |
|
5 |
<artifactId>dnet45-parent</artifactId> |
|
6 |
<version>1.0.0</version> |
|
7 |
<relativePath /> |
|
8 |
</parent> |
|
9 |
<modelVersion>4.0.0</modelVersion> |
|
10 |
<groupId>eu.dnetlib</groupId> |
|
11 |
<artifactId>cnr-enabling-services</artifactId> |
|
12 |
<packaging>jar</packaging> |
|
13 |
<version>2.2.2</version> |
|
14 |
<scm> |
|
15 |
<developerConnection>scm:svn:https://svn.driver.research-infrastructures.eu/driver/dnet45/modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2</developerConnection> |
|
16 |
</scm> |
|
17 |
<dependencies> |
|
18 |
<dependency> |
|
19 |
<groupId>commons-beanutils</groupId> |
|
20 |
<artifactId>commons-beanutils</artifactId> |
|
21 |
<version>1.8.0</version> |
|
22 |
</dependency> |
|
23 |
<dependency> |
|
24 |
<groupId>apache</groupId> |
|
25 |
<artifactId>oro</artifactId> |
|
26 |
<version>2.0.8</version> |
|
27 |
</dependency> |
|
28 |
<dependency> |
|
29 |
<groupId>com.google.guava</groupId> |
|
30 |
<artifactId>guava</artifactId> |
|
31 |
<version>${google.guava.version}</version> |
|
32 |
</dependency> |
|
33 |
<dependency> |
|
34 |
<groupId>org.quartz-scheduler</groupId> |
|
35 |
<artifactId>quartz</artifactId> |
|
36 |
<version>${quartz.version}</version> |
|
37 |
</dependency> |
|
38 |
|
|
39 |
<dependency> |
|
40 |
<groupId>org.springframework</groupId> |
|
41 |
<artifactId>spring-beans</artifactId> |
|
42 |
<version>${spring.version}</version> |
|
43 |
</dependency> |
|
44 |
<dependency> |
|
45 |
<groupId>org.springframework</groupId> |
|
46 |
<artifactId>spring-jdbc</artifactId> |
|
47 |
<version>${spring.version}</version> |
|
48 |
</dependency> |
|
49 |
<dependency> |
|
50 |
<groupId>org.springframework</groupId> |
|
51 |
<artifactId>spring-tx</artifactId> |
|
52 |
<version>${spring.version}</version> |
|
53 |
</dependency> |
|
54 |
<dependency> |
|
55 |
<groupId>org.springframework</groupId> |
|
56 |
<artifactId>spring-orm</artifactId> |
|
57 |
<version>${spring.version}</version> |
|
58 |
</dependency> |
|
59 |
<dependency> |
|
60 |
<groupId>org.postgresql</groupId> |
|
61 |
<artifactId>jdbc4driver</artifactId> |
|
62 |
<version>8.3</version> |
|
63 |
</dependency> |
|
64 |
<dependency> |
|
65 |
<groupId>org.xerial</groupId> |
|
66 |
<artifactId>sqlite-jdbc</artifactId> |
|
67 |
<version>3.7.2</version> |
|
68 |
</dependency> |
|
69 |
<dependency> |
|
70 |
<groupId>org.hibernate</groupId> |
|
71 |
<artifactId>hibernate-core</artifactId> |
|
72 |
<version>4.3.2.Final</version> |
|
73 |
<exclusions> |
|
74 |
<exclusion> |
|
75 |
<artifactId>antlr</artifactId> |
|
76 |
<groupId>antlr</groupId> |
|
77 |
</exclusion> |
|
78 |
</exclusions> |
|
79 |
</dependency> |
|
80 |
<dependency> |
|
81 |
<groupId>commons-collections</groupId> |
|
82 |
<artifactId>commons-collections</artifactId> |
|
83 |
<version>${commons.collections.version}</version> |
|
84 |
</dependency> |
|
85 |
<dependency> |
|
86 |
<groupId>commons-dbcp</groupId> |
|
87 |
<artifactId>commons-dbcp</artifactId> |
|
88 |
<version>1.4</version> |
|
89 |
</dependency> |
|
90 |
<dependency> |
|
91 |
<groupId>eu.dnetlib</groupId> |
|
92 |
<artifactId>cnr-rmi-api</artifactId> |
|
93 |
<version>[2.0.0,3.0.0)</version> |
|
94 |
</dependency> |
|
95 |
<dependency> |
|
96 |
<groupId>eu.dnetlib</groupId> |
|
97 |
<artifactId>cnr-misc-utils</artifactId> |
|
98 |
<version>[1.0.0,2.0.0)</version> |
|
99 |
</dependency> |
|
100 |
<dependency> |
|
101 |
<groupId>eu.dnetlib</groupId> |
|
102 |
<artifactId>cnr-service-utils</artifactId> |
|
103 |
<version>[1.0.0,2.0.0)</version> |
|
104 |
</dependency> |
|
105 |
<dependency> |
|
106 |
<groupId>eu.dnetlib</groupId> |
|
107 |
<artifactId>cnr-blackboard-common</artifactId> |
|
108 |
<version>[2.1.0,3.0.0)</version> |
|
109 |
</dependency> |
|
110 |
<dependency> |
|
111 |
<groupId>eu.dnetlib</groupId> |
|
112 |
<artifactId>cnr-xmldb</artifactId> |
|
113 |
<version>[2.0.0,3.0.0)</version> |
|
114 |
<exclusions> |
|
115 |
<exclusion> |
|
116 |
<artifactId>commons-collections</artifactId> |
|
117 |
<groupId>apache</groupId> |
|
118 |
</exclusion> |
|
119 |
</exclusions> |
|
120 |
</dependency> |
|
121 |
<dependency> |
|
122 |
<groupId>com.google.code.gson</groupId> |
|
123 |
<artifactId>gson</artifactId> |
|
124 |
<version>${google.gson.version}</version> |
|
125 |
</dependency> |
|
126 |
<dependency> |
|
127 |
<groupId>com.sun.xml.messaging.saaj</groupId> |
|
128 |
<artifactId>saaj-impl</artifactId> |
|
129 |
<version>1.3</version> |
|
130 |
</dependency> |
|
131 |
<dependency> |
|
132 |
<groupId>jaxen</groupId> |
|
133 |
<artifactId>jaxen</artifactId> |
|
134 |
<version>1.1.6</version> |
|
135 |
</dependency> |
|
136 |
|
|
137 |
<!-- TEST DEPS --> |
|
138 |
<dependency> |
|
139 |
<groupId>hsqldb</groupId> |
|
140 |
<artifactId>hsqldb</artifactId> |
|
141 |
<version>1.8.0.7</version> |
|
142 |
<scope>test</scope> |
|
143 |
</dependency> |
|
144 |
<dependency> |
|
145 |
<groupId>org.aspectj</groupId> |
|
146 |
<artifactId>aspectjrt</artifactId> |
|
147 |
<version>1.6.3</version> |
|
148 |
<scope>test</scope> |
|
149 |
</dependency> |
|
150 |
<dependency> |
|
151 |
<groupId>org.aspectj</groupId> |
|
152 |
<artifactId>aspectjweaver</artifactId> |
|
153 |
<version>1.6.3</version> |
|
154 |
<scope>test</scope> |
|
155 |
</dependency> |
|
156 |
<dependency> |
|
157 |
<groupId>org.hibernate</groupId> |
|
158 |
<artifactId>hibernate-annotations</artifactId> |
|
159 |
<version>3.3.1</version> |
|
160 |
<scope>test</scope> |
|
161 |
</dependency> |
|
162 |
<dependency> |
|
163 |
<groupId>xerces</groupId> |
|
164 |
<artifactId>xercesImpl</artifactId> |
|
165 |
<version>2.11.0</version> |
|
166 |
<scope>test</scope> |
|
167 |
</dependency> |
|
168 |
<dependency> |
|
169 |
<groupId>eu.dnetlib</groupId> |
|
170 |
<artifactId>cnr-test-utils</artifactId> |
|
171 |
<version>[1.0.0,2.0.0)</version> |
|
172 |
<scope>test</scope> |
|
173 |
</dependency> |
|
174 |
<dependency> |
|
175 |
<groupId>org.springframework</groupId> |
|
176 |
<artifactId>spring-webmvc</artifactId> |
|
177 |
<version>${spring.version}</version> |
|
178 |
<scope>test</scope> |
|
179 |
</dependency> |
|
180 |
<dependency> |
|
181 |
<groupId>org.springframework</groupId> |
|
182 |
<artifactId>spring-test</artifactId> |
|
183 |
<version>${spring.version}</version> |
|
184 |
<scope>test</scope> |
|
185 |
</dependency> |
|
186 |
<dependency> |
|
187 |
<groupId>org.apache.cxf</groupId> |
|
188 |
<artifactId>cxf-rt-frontend-jaxws</artifactId> |
|
189 |
<version>${cxf.version}</version> |
|
190 |
</dependency> |
|
191 |
<dependency> |
|
192 |
<groupId>org.apache.cxf</groupId> |
|
193 |
<artifactId>cxf-rt-ws-policy</artifactId> |
|
194 |
<version>${cxf.version}</version> |
|
195 |
<scope>test</scope> |
|
196 |
</dependency> |
|
197 |
<dependency> |
|
198 |
<groupId>org.apache.cxf</groupId> |
|
199 |
<artifactId>cxf-rt-frontend-jaxrs</artifactId> |
|
200 |
<scope>test</scope> |
|
201 |
<version>${cxf.version}</version> |
|
202 |
</dependency> |
|
203 |
|
|
204 |
<dependency> |
|
205 |
<groupId>org.apache.cxf</groupId> |
|
206 |
<artifactId>cxf-rt-transports-local</artifactId> |
|
207 |
<version>${cxf.version}</version> |
|
208 |
<scope>test</scope> |
|
209 |
</dependency> |
|
210 |
|
|
211 |
<dependency> |
|
212 |
<groupId>org.apache.cxf</groupId> |
|
213 |
<artifactId>cxf-rt-ws-rm</artifactId> |
|
214 |
<version>${cxf.version}</version> |
|
215 |
<scope>test</scope> |
|
216 |
</dependency> |
|
217 |
<dependency> |
|
218 |
<groupId>org.mockito</groupId> |
|
219 |
<artifactId>mockito-core</artifactId> |
|
220 |
<version>${mockito.version}</version> |
|
221 |
<scope>test</scope> |
|
222 |
</dependency> |
|
223 |
<dependency> |
|
224 |
<groupId>junit</groupId> |
|
225 |
<artifactId>junit</artifactId> |
|
226 |
<version>${junit.version}</version> |
|
227 |
<scope>test</scope> |
|
228 |
</dependency> |
|
229 |
</dependencies> |
|
230 |
</project> |
modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2/src/main/java/eu/dnetlib/enabling/is/sn/AbstractNotificationSender.java | ||
---|---|---|
1 |
package eu.dnetlib.enabling.is.sn; |
|
2 |
|
|
3 |
|
|
4 |
/** |
|
5 |
* NotificationSender interface defines an injection point for the NotificationInvoker instance. |
|
6 |
* |
|
7 |
* <p> |
|
8 |
* It will be fairly common for implementors of NotificationSender to back the invoker reference into an instance |
|
9 |
* variable. This abstract class offers this for free. </p> |
|
10 |
* |
|
11 |
* @author marko |
|
12 |
* |
|
13 |
*/ |
|
14 |
public abstract class AbstractNotificationSender implements NotificationSender { |
|
15 |
|
|
16 |
/** |
|
17 |
* notification invoker used to send messages to destinations. |
|
18 |
*/ |
|
19 |
private NotificationInvoker invoker; |
|
20 |
|
|
21 |
public NotificationInvoker getInvoker() { |
|
22 |
return invoker; |
|
23 |
} |
|
24 |
|
|
25 |
@Override |
|
26 |
public void setInvoker(final NotificationInvoker invoker) { |
|
27 |
this.invoker = invoker; |
|
28 |
} |
|
29 |
|
|
30 |
} |
modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2/src/main/java/eu/dnetlib/enabling/is/registry/RegistryBlackboardManagerImpl.java | ||
---|---|---|
1 |
package eu.dnetlib.enabling.is.registry; |
|
2 |
|
|
3 |
import javax.xml.transform.dom.DOMResult; |
|
4 |
import javax.xml.xpath.XPathConstants; |
|
5 |
import javax.xml.xpath.XPathExpressionException; |
|
6 |
import javax.xml.xpath.XPathFactory; |
|
7 |
|
|
8 |
import org.apache.commons.logging.Log; |
|
9 |
import org.apache.commons.logging.LogFactory; |
|
10 |
import org.springframework.beans.factory.annotation.Required; |
|
11 |
import org.w3c.dom.Document; |
|
12 |
import org.w3c.dom.Element; |
|
13 |
import org.w3c.dom.Node; |
|
14 |
|
|
15 |
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService; |
|
16 |
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService; |
|
17 |
import eu.dnetlib.enabling.tools.OpaqueResource; |
|
18 |
import eu.dnetlib.enabling.tools.StringOpaqueResource; |
|
19 |
import eu.dnetlib.enabling.tools.blackboard.BlackboardMessage; |
|
20 |
import eu.dnetlib.miscutils.datetime.DateUtils; |
|
21 |
import eu.dnetlib.miscutils.jaxb.JaxbFactory; |
|
22 |
|
|
23 |
/** |
|
24 |
* Simple registry blackboard manager implementation. |
|
25 |
* |
|
26 |
* @author marko |
|
27 |
* |
|
28 |
*/ |
|
29 |
public class RegistryBlackboardManagerImpl implements RegistryBlackboardManager { // NOPMD |
|
30 |
|
|
31 |
/** |
|
32 |
* logger. |
|
33 |
*/ |
|
34 |
private static final Log log = LogFactory.getLog(RegistryBlackboardManagerImpl.class); // NOPMD by marko on 11/24/08 5:02 PM |
|
35 |
|
|
36 |
/** |
|
37 |
* timestamp padding. |
|
38 |
*/ |
|
39 |
private static final String PADDING = "000"; |
|
40 |
|
|
41 |
/** |
|
42 |
* milliseconds in a second. |
|
43 |
*/ |
|
44 |
private static final int MILLIS = 1000; |
|
45 |
|
|
46 |
/** |
|
47 |
* IS Lookup |
|
48 |
*/ |
|
49 |
private ISLookUpService isLookup; |
|
50 |
|
|
51 |
/** |
|
52 |
* the registry which is bound with this registry blackboard manager implementation. |
|
53 |
*/ |
|
54 |
private ISRegistryService registryService; |
|
55 |
|
|
56 |
/** |
|
57 |
* blackboard message factory. |
|
58 |
*/ |
|
59 |
private JaxbFactory<BlackboardMessage> messageFactory; |
|
60 |
|
|
61 |
/** |
|
62 |
* provides the current date. Testers can override. |
|
63 |
*/ |
|
64 |
private MessageDater messageDater = new MessageDater(); |
|
65 |
|
|
66 |
/** |
|
67 |
* Testers can override. |
|
68 |
* |
|
69 |
* @author marko |
|
70 |
* |
|
71 |
*/ |
|
72 |
public static class MessageDater { |
|
73 |
|
|
74 |
public String getCurrentDate() { |
|
75 |
return DateUtils.now_ISO8601(); |
|
76 |
} |
|
77 |
|
|
78 |
public String getNumericStamp() { |
|
79 |
return Long.toString(System.currentTimeMillis() / MILLIS) + "." + System.currentTimeMillis() % MILLIS + PADDING; |
|
80 |
} |
|
81 |
} |
|
82 |
|
|
83 |
/** |
|
84 |
* LAST_REQUEST or LAST_RESPONSE blackboard time stamp holders. |
|
85 |
* |
|
86 |
* @author marko |
|
87 |
* |
|
88 |
*/ |
|
89 |
public enum LastStamp { |
|
90 |
/** |
|
91 |
* LAST_REQUEST, used when the blackboard message flows from the client to the server. |
|
92 |
*/ |
|
93 |
REQUEST, |
|
94 |
|
|
95 |
/** |
|
96 |
* LAST_RESPONSE, used when the blackboard message flows from the server to the client, signaling the completion/progress of the |
|
97 |
* action.. |
|
98 |
*/ |
|
99 |
RESPONSE |
|
100 |
} |
|
101 |
|
|
102 |
/** |
|
103 |
* {@inheritDoc} |
|
104 |
* |
|
105 |
* @see eu.dnetlib.enabling.is.registry.RegistryBlackboardManager#addMessage(java.lang.String, java.lang.String, java.lang.String) |
|
106 |
*/ |
|
107 |
@Override |
|
108 |
public void addMessage(final String profId, final String messageId, final String message) { // NOPMD |
|
109 |
try { |
|
110 |
final BlackboardMessage bbm = messageFactory.parse(message); |
|
111 |
bbm.setDate(messageDater.getCurrentDate()); // preserve compatibility. |
|
112 |
|
|
113 |
if (bbm.getId() == null || !bbm.getId().equals(messageId)) { throw new IllegalArgumentException("invalid blackboard message id"); } |
|
114 |
|
|
115 |
synchronized (this) { |
|
116 |
final OpaqueResource serviceProfile = new StringOpaqueResource(isLookup.getResourceProfile(profId)); |
|
117 |
|
|
118 |
final Document doc = serviceProfile.asDom(); |
|
119 |
final Node bboard = (Node) XPathFactory.newInstance().newXPath().evaluate("//BLACKBOARD", doc, XPathConstants.NODE); |
|
120 |
|
|
121 |
// delete current element if exists |
|
122 |
final Node messageElement = (Node) XPathFactory.newInstance().newXPath().evaluate("//BLACKBOARD/MESSAGE[@id='" + messageId + "']", doc, |
|
123 |
XPathConstants.NODE); |
|
124 |
|
|
125 |
if (messageElement != null) { |
|
126 |
bboard.removeChild(messageElement); |
|
127 |
} |
|
128 |
|
|
129 |
// append the serialized node to the blackboard node |
|
130 |
messageFactory.serialize(bbm, new DOMResult(bboard)); |
|
131 |
|
|
132 |
updateLastStamps(doc, LastStamp.REQUEST, messageId); |
|
133 |
|
|
134 |
registryService.updateProfile(profId, serviceProfile.asString(), serviceProfile.getResourceType()); |
|
135 |
} |
|
136 |
} catch (Exception e) { |
|
137 |
throw new IllegalStateException(e); |
|
138 |
} |
|
139 |
} |
|
140 |
|
|
141 |
/** |
|
142 |
* Helper method which updates the LAST_* stamps in the blackboard header. |
|
143 |
* |
|
144 |
* @param doc |
|
145 |
* profile DOM document |
|
146 |
* @param stamp |
|
147 |
* which stamp to modify |
|
148 |
* @param messageId |
|
149 |
* message id to point the stamp to |
|
150 |
* @throws XPathExpressionException |
|
151 |
* could happen |
|
152 |
*/ |
|
153 |
protected void updateLastStamps(final Document doc, final LastStamp stamp, final String messageId) throws XPathExpressionException { |
|
154 |
final Element lastRequest = (Element) XPathFactory.newInstance().newXPath().evaluate("//BLACKBOARD/LAST_" + stamp, doc, XPathConstants.NODE); |
|
155 |
lastRequest.setTextContent(messageId); |
|
156 |
lastRequest.setAttribute("date", messageDater.getNumericStamp()); |
|
157 |
} |
|
158 |
|
|
159 |
/** |
|
160 |
* {@inheritDoc} |
|
161 |
* |
|
162 |
* @see eu.dnetlib.enabling.is.registry.RegistryBlackboardManager#deleteMessage(java.lang.String, java.lang.String) |
|
163 |
*/ |
|
164 |
@Override |
|
165 |
public void deleteMessage(final String profId, final String messageId) { |
|
166 |
try { |
|
167 |
synchronized (this) { |
|
168 |
final OpaqueResource serviceProfile = new StringOpaqueResource(isLookup.getResourceProfile(profId)); |
|
169 |
final Document doc = serviceProfile.asDom(); |
|
170 |
|
|
171 |
final Node message = (Node) XPathFactory.newInstance().newXPath().evaluate("//BLACKBOARD/MESSAGE[@id='" + messageId + "']", doc, |
|
172 |
XPathConstants.NODE); |
|
173 |
|
|
174 |
message.getParentNode().removeChild(message); |
|
175 |
|
|
176 |
registryService.updateProfile(profId, serviceProfile.asString(), serviceProfile.getResourceType()); |
|
177 |
} |
|
178 |
log.debug("Deleted bb message " + messageId + " from profile " + profId); |
|
179 |
} catch (Exception e) { |
|
180 |
log.error("Error deleting bb message " + messageId + " from profile " + profId, e); |
|
181 |
throw new IllegalStateException(e); |
|
182 |
} |
|
183 |
} |
|
184 |
|
|
185 |
/** |
|
186 |
* {@inheritDoc} |
|
187 |
* |
|
188 |
* @see eu.dnetlib.enabling.is.registry.RegistryBlackboardManager#replyMessage(java.lang.String, java.lang.String) |
|
189 |
*/ |
|
190 |
@Override |
|
191 |
public void replyMessage(final String profId, final String message) { |
|
192 |
try { |
|
193 |
final BlackboardMessage bbm = messageFactory.parse(message); |
|
194 |
bbm.setDate(messageDater.getCurrentDate()); // preserve compatibility. |
|
195 |
|
|
196 |
final String messageId = bbm.getId(); |
|
197 |
|
|
198 |
synchronized (this) { |
|
199 |
final OpaqueResource serviceProfile = new StringOpaqueResource(isLookup.getResourceProfile(profId)); |
|
200 |
final Document doc = serviceProfile.asDom(); |
|
201 |
|
|
202 |
final Node messageElement = (Node) XPathFactory.newInstance().newXPath().evaluate("//BLACKBOARD/MESSAGE[@id='" + messageId + "']", doc, |
|
203 |
XPathConstants.NODE); |
|
204 |
|
|
205 |
if (messageElement == null) { throw new IllegalArgumentException("no such blackboard message " + messageId + ". Unably to reply"); } |
|
206 |
|
|
207 |
final Node bboard = messageElement.getParentNode(); |
|
208 |
bboard.removeChild(messageElement); |
|
209 |
|
|
210 |
// append the serialized node to the blackboard node |
|
211 |
messageFactory.serialize(bbm, new DOMResult(bboard)); |
|
212 |
|
|
213 |
updateLastStamps(doc, LastStamp.RESPONSE, messageId); |
|
214 |
|
|
215 |
registryService.updateProfile(profId, serviceProfile.asString(), serviceProfile.getResourceType()); |
|
216 |
} |
|
217 |
} catch (Exception e) { |
|
218 |
throw new IllegalStateException(e); |
|
219 |
} |
|
220 |
} |
|
221 |
|
|
222 |
public ISRegistryService getRegistryService() { |
|
223 |
return registryService; |
|
224 |
} |
|
225 |
|
|
226 |
@Required |
|
227 |
public void setRegistryService(final ISRegistryService registryService) { |
|
228 |
this.registryService = registryService; |
|
229 |
} |
|
230 |
|
|
231 |
public JaxbFactory<BlackboardMessage> getMessageFactory() { |
|
232 |
return messageFactory; |
|
233 |
} |
|
234 |
|
|
235 |
@Required |
|
236 |
public void setMessageFactory(final JaxbFactory<BlackboardMessage> messageFactory) { |
|
237 |
this.messageFactory = messageFactory; |
|
238 |
} |
|
239 |
|
|
240 |
public MessageDater getMessageDater() { |
|
241 |
return messageDater; |
|
242 |
} |
|
243 |
|
|
244 |
public void setMessageDater(final MessageDater messageDater) { |
|
245 |
this.messageDater = messageDater; |
|
246 |
} |
|
247 |
|
|
248 |
public ISLookUpService getIsLookup() { |
|
249 |
return isLookup; |
|
250 |
} |
|
251 |
|
|
252 |
@Required |
|
253 |
public void setIsLookup(final ISLookUpService isLookup) { |
|
254 |
this.isLookup = isLookup; |
|
255 |
} |
|
256 |
|
|
257 |
} |
modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2/src/main/java/eu/dnetlib/enabling/is/sn/NotificationDetector.java | ||
---|---|---|
1 |
package eu.dnetlib.enabling.is.sn; |
|
2 |
|
|
3 |
|
|
4 |
/** |
|
5 |
* Implementors of this interface are able to detect events which will trigger notifications. |
|
6 |
* @author marko |
|
7 |
* |
|
8 |
*/ |
|
9 |
public interface NotificationDetector { |
|
10 |
|
|
11 |
/** |
|
12 |
* injection point for NotificationSender. |
|
13 |
* |
|
14 |
* @param sender sender |
|
15 |
*/ |
|
16 |
void setSender(NotificationSender sender); |
|
17 |
} |
modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2/src/main/java/eu/dnetlib/enabling/is/sn/SynchronousNotificationSenderImpl.java | ||
---|---|---|
1 |
package eu.dnetlib.enabling.is.sn; |
|
2 |
|
|
3 |
import javax.xml.ws.wsaddressing.W3CEndpointReference; |
|
4 |
|
|
5 |
import org.apache.commons.logging.Log; |
|
6 |
import org.apache.commons.logging.LogFactory; |
|
7 |
|
|
8 |
/** |
|
9 |
* This implementation of NotificationSender simply sends notification synchronously. |
|
10 |
* |
|
11 |
* NOTE: this is only for testing. Real-wold cases should use AsynchrnonousNotificationSender, because we have to |
|
12 |
* get out the thread serving eXist queries. |
|
13 |
* |
|
14 |
* @author marko |
|
15 |
* |
|
16 |
*/ |
|
17 |
public class SynchronousNotificationSenderImpl extends AbstractNotificationSender { |
|
18 |
|
|
19 |
/** |
|
20 |
* logger. |
|
21 |
*/ |
|
22 |
private static final Log log = LogFactory.getLog(SynchronousNotificationSenderImpl.class); // NOPMD by marko on 11/24/08 5:02 PM |
|
23 |
|
|
24 |
/** |
|
25 |
* {@inheritDoc} |
|
26 |
* |
|
27 |
* @see eu.dnetlib.enabling.is.sn.NotificationSender#send(javax.xml.ws.wsaddressing.W3CEndpointReference, |
|
28 |
* eu.dnetlib.enabling.is.sn.NotificationMessage) |
|
29 |
*/ |
|
30 |
@Override |
|
31 |
public void send(final W3CEndpointReference destination, final NotificationMessage message) { |
|
32 |
log.info("synchronously sending message " + message.getSubscriptionId() + ", " + message.getTopic() + ", " + message.getResourceId() + ", " |
|
33 |
+ message.getBody()); |
|
34 |
try { |
|
35 |
getInvoker().send(destination, message, 0); |
|
36 |
} catch (javax.xml.ws.soap.SOAPFaultException t) { |
|
37 |
log.fatal("error sending notification to " + destination.toString(), t); |
|
38 |
} |
|
39 |
} |
|
40 |
} |
modules/cnr-enabling-services/tags/cnr-enabling-services-2.2.2/src/main/java/eu/dnetlib/enabling/is/registry/ISRegistryServiceImpl.java | ||
---|---|---|
1 |
package eu.dnetlib.enabling.is.registry; // NOPMD |
|
2 |
|
|
3 |
import java.io.IOException; |
|
4 |
import java.util.Date; |
|
5 |
import java.util.List; |
|
6 |
|
|
7 |
import javax.annotation.Resource; |
|
8 |
import javax.jws.WebService; |
|
9 |
import javax.xml.parsers.ParserConfigurationException; |
|
10 |
import javax.xml.xpath.XPath; |
|
11 |
import javax.xml.xpath.XPathConstants; |
|
12 |
import javax.xml.xpath.XPathExpressionException; |
|
13 |
import javax.xml.xpath.XPathFactory; |
|
14 |
|
|
15 |
import org.apache.commons.logging.Log; |
|
16 |
import org.apache.commons.logging.LogFactory; |
|
17 |
import org.springframework.beans.factory.annotation.Required; |
|
18 |
import org.w3c.dom.Element; |
|
19 |
import org.xml.sax.SAXException; |
|
20 |
|
|
21 |
import com.sun.xml.messaging.saaj.util.Base64; |
|
22 |
|
|
23 |
import eu.dnetlib.common.rmi.APIDeprecatedException; |
|
24 |
import eu.dnetlib.common.rmi.UnimplementedException; |
|
25 |
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException; |
|
26 |
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException; |
|
27 |
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService; |
|
28 |
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException; |
|
29 |
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService; |
|
30 |
import eu.dnetlib.enabling.is.registry.schema.OpaqueResourceValidator; |
|
31 |
import eu.dnetlib.enabling.is.registry.schema.ValidationException; |
|
32 |
import eu.dnetlib.enabling.is.registry.validation.ProfileValidationStrategy; |
|
33 |
import eu.dnetlib.enabling.is.registry.validation.RegistrationPhase; |
|
34 |
import eu.dnetlib.enabling.is.store.rmi.ISStoreException; |
|
35 |
import eu.dnetlib.enabling.is.store.rmi.ISStoreService; |
|
36 |
import eu.dnetlib.enabling.tools.AbstractBaseService; |
|
37 |
import eu.dnetlib.enabling.tools.CompatResourceIdentifierResolverImpl; |
|
38 |
import eu.dnetlib.enabling.tools.OpaqueResource; |
|
39 |
import eu.dnetlib.enabling.tools.ResourceIdentifierResolver; |
|
40 |
import eu.dnetlib.enabling.tools.ResourceType; |
|
41 |
import eu.dnetlib.enabling.tools.StringOpaqueResource; |
|
42 |
import eu.dnetlib.enabling.tools.UniqueIdentifierGenerator; |
|
43 |
import eu.dnetlib.enabling.tools.UniqueIdentifierGeneratorImpl; |
|
44 |
import eu.dnetlib.enabling.tools.XQueryUtils; |
|
45 |
|
|
46 |
/** |
|
47 |
* Registry service implementation. |
|
48 |
* |
|
49 |
* @author marko |
|
50 |
* |
|
51 |
*/ |
|
52 |
@WebService(targetNamespace = "http://services.dnetlib.eu/") |
|
53 |
public class ISRegistryServiceImpl extends AbstractBaseService implements ISRegistryService { // NOPMD by marko on |
|
54 |
|
|
55 |
/** |
|
56 |
* logger. |
|
57 |
*/ |
|
58 |
private static final Log log = LogFactory.getLog(ISRegistryServiceImpl.class); // NOPMD by marko on 11/24/08 5:02 PM |
|
59 |
|
|
60 |
/** |
|
61 |
* error message: secure profile registration. |
|
62 |
*/ |
|
63 |
private static final String ERROR_SEC_PROFILE = "cannot register secure profile"; |
|
64 |
|
|
65 |
/** |
|
66 |
* error message: trying to retrieve the current stored version of the resource profile. |
|
67 |
*/ |
|
68 |
private static final String CANT_FETCH = "cannot fetch original profile"; |
|
69 |
|
|
70 |
/** |
|
71 |
* error message: cannot create a resource. |
|
72 |
*/ |
|
73 |
private static final String CANT_CREATE = "cannot create resource"; |
|
74 |
|
|
75 |
/** |
|
76 |
* IS Store |
|
77 |
*/ |
|
78 |
private ISStoreService isStore; |
|
79 |
|
|
80 |
/** |
|
81 |
* IS Lookup |
|
82 |
*/ |
|
83 |
private ISLookUpService isLookup; |
|
84 |
|
|
85 |
/** |
|
86 |
* uuid generator. |
|
87 |
*/ |
|
88 |
@Resource |
|
89 |
private UniqueIdentifierGenerator uuidGenerator = new UniqueIdentifierGeneratorImpl(); |
|
90 |
|
|
91 |
/** |
|
92 |
* manages the pending state of resource. Different implementations can be plugged in. |
|
93 |
*/ |
|
94 |
private PendingResourceManager pendingManager = new CompatPendingResourceManagerImpl(); |
|
95 |
|
|
96 |
/** |
|
97 |
* manages resource identifier mappings with the abstract xmldb namespace (files/collections). |
|
98 |
*/ |
|
99 |
@Resource |
|
100 |
private ResourceIdentifierResolver resIdResolver = new CompatResourceIdentifierResolverImpl(); |
|
101 |
|
|
102 |
/** |
|
103 |
* used to validate resources. |
|
104 |
*/ |
|
105 |
private OpaqueResourceValidator resourceValidator; |
|
106 |
|
|
107 |
/** |
|
108 |
* used to validate resources w.r.t. a set of defined properties. |
|
109 |
*/ |
|
110 |
@Resource |
|
111 |
private ProfileValidationStrategy profileValidationStrategy; |
|
112 |
|
|
113 |
/** |
|
114 |
* query utils. Used to obtain xmldb collection names and other things useful for interacting with the IS_Store. |
|
115 |
*/ |
|
116 |
private XQueryUtils xqueryUtils; |
|
117 |
|
|
118 |
/** |
|
119 |
* the blackboard management stuff is factored out here. |
|
120 |
*/ |
|
121 |
@Resource |
|
122 |
private RegistryBlackboardManager blackboardManager; |
|
123 |
|
|
124 |
@Override |
|
125 |
public void start() { |
|
126 |
super.start(); |
|
127 |
} |
|
128 |
|
|
129 |
/** |
|
130 |
* {@inheritDoc} |
|
131 |
* |
|
132 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#addBlackBoardMessage(java.lang.String, java.lang.String, java.lang.String) |
|
133 |
*/ |
|
134 |
@Override |
|
135 |
public void addBlackBoardMessage(final String profId, final String messageId, final String message) throws ISRegistryException { |
|
136 |
blackboardManager.addMessage(profId, messageId, message); |
|
137 |
} |
|
138 |
|
|
139 |
/** |
|
140 |
* {@inheritDoc} |
|
141 |
* |
|
142 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#addOrUpdateResourceType(java.lang.String, java.lang.String) |
|
143 |
*/ |
|
144 |
@Override |
|
145 |
public boolean addOrUpdateResourceType(final String resourceType, final String resourceSchema) throws ISRegistryException { |
|
146 |
return addResourceType(resourceType, resourceSchema); |
|
147 |
} |
|
148 |
|
|
149 |
/** |
|
150 |
* {@inheritDoc} |
|
151 |
* |
|
152 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#addProfileNode(java.lang.String, java.lang.String, java.lang.String) |
|
153 |
*/ |
|
154 |
@Override |
|
155 |
public boolean addProfileNode(final String profId, final String xpath, final String node) throws ISRegistryException { |
|
156 |
// TODO Auto-generated method stub |
|
157 |
throw new UnimplementedException(); |
|
158 |
} |
|
159 |
|
|
160 |
/** |
|
161 |
* {@inheritDoc} |
|
162 |
* |
|
163 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#addResourceType(java.lang.String, java.lang.String) |
|
164 |
*/ |
|
165 |
@Override |
|
166 |
public boolean addResourceType(final String resourceType, final String resourceSchema) throws ISRegistryException { |
|
167 |
try { |
|
168 |
return isStore.insertXML(resourceType, xqueryUtils.getRootCollection() + ResourceType.RESOURCE_TYPES, |
|
169 |
resourceSchema); |
|
170 |
} catch (ISStoreException e) { |
|
171 |
throw new ISRegistryException("cannot add resource type", e); |
|
172 |
} |
|
173 |
} |
|
174 |
|
|
175 |
/** |
|
176 |
* {@inheritDoc} |
|
177 |
* |
|
178 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#deleteBlackBoardMessage(java.lang.String, java.lang.String) |
|
179 |
*/ |
|
180 |
@Override |
|
181 |
public void deleteBlackBoardMessage(final String profId, final String messageId) throws ISRegistryException { |
|
182 |
blackboardManager.deleteMessage(profId, messageId); |
|
183 |
} |
|
184 |
|
|
185 |
/** |
|
186 |
* {@inheritDoc} |
|
187 |
* |
|
188 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#deleteProfile(java.lang.String) |
|
189 |
*/ |
|
190 |
@Override |
|
191 |
public boolean deleteProfile(final String resId) throws ISRegistryException { |
|
192 |
try { |
|
193 |
final boolean res = isStore.deleteXML(resIdResolver.getFileName(resId), |
|
194 |
"/db/DRIVER/" + resIdResolver.getCollectionName(resId)); |
|
195 |
if (!res) { throw new ISRegistryDocumentNotFoundException("document " + resId + " not found"); } |
|
196 |
|
|
197 |
return true; |
|
198 |
} catch (ISStoreException e) { |
|
199 |
throw new ISRegistryException("cannot delete profile " + resId, e); |
|
200 |
} |
|
201 |
} |
|
202 |
|
|
203 |
/** |
|
204 |
* {@inheritDoc} |
|
205 |
* |
|
206 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#deleteProfiles(java.util.List) |
|
207 |
*/ |
|
208 |
@Override |
|
209 |
public boolean deleteProfiles(final List<String> arrayprofId) throws ISRegistryException { |
|
210 |
throw new APIDeprecatedException(); |
|
211 |
} |
|
212 |
|
|
213 |
/** |
|
214 |
* {@inheritDoc} |
|
215 |
* |
|
216 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#deleteResourceType(java.lang.String, java.lang.Boolean) |
|
217 |
*/ |
|
218 |
@Override |
|
219 |
public boolean deleteResourceType(final String resourceType, final Boolean hierarchical) throws ISRegistryException { |
|
220 |
try { |
|
221 |
return isStore.deleteXML(resourceType, xqueryUtils.getRootCollection() + ResourceType.RESOURCE_TYPES); |
|
222 |
} catch (ISStoreException e) { |
|
223 |
throw new ISRegistryException("error deleting resource type " + resourceType, e); |
|
224 |
} |
|
225 |
} |
|
226 |
|
|
227 |
/** |
|
228 |
* {@inheritDoc} |
|
229 |
* |
|
230 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#executeXUpdate(java.lang.String) |
|
231 |
*/ |
|
232 |
@Override |
|
233 |
public boolean executeXUpdate(final String xquery) throws ISRegistryException { |
|
234 |
try { |
|
235 |
return isStore.executeXUpdate(xquery); |
|
236 |
} catch (ISStoreException e) { |
|
237 |
throw new ISRegistryException(e); |
|
238 |
} |
|
239 |
} |
|
240 |
|
|
241 |
/** |
|
242 |
* {@inheritDoc} |
|
243 |
* |
|
244 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#insertProfileForValidation(java.lang.String, java.lang.String) |
|
245 |
*/ |
|
246 |
@Override |
|
247 |
public String insertProfileForValidation(final String resourceType, final String resourceProfile) throws ISRegistryException { |
|
248 |
try { |
|
249 |
final OpaqueResource resource = new StringOpaqueResource(resourceProfile); |
|
250 |
if (!resourceType.equals(resource.getResourceType())) { throw new ISRegistryException("expected resource type doesn't match to resource"); } |
|
251 |
|
|
252 |
pendingManager.setPending(resource, true); |
|
253 |
|
|
254 |
return registerProfile(resource.asString()); |
|
255 |
} catch (XPathExpressionException e) { |
|
256 |
throw new ISRegistryException(e); |
|
257 |
} catch (SAXException e) { |
|
258 |
throw new ISRegistryException(e); |
|
259 |
} catch (IOException e) { |
|
260 |
throw new ISRegistryException(e); |
|
261 |
} catch (ParserConfigurationException e) { |
|
262 |
throw new ISRegistryException(e); |
|
263 |
} |
|
264 |
} |
|
265 |
|
|
266 |
/** |
|
267 |
* {@inheritDoc} |
|
268 |
* |
|
269 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#refreshProfile(java.lang.String, java.lang.String) |
|
270 |
*/ |
|
271 |
@Override |
|
272 |
public boolean refreshProfile(final String profId, final String resourceType) throws ISRegistryException { |
|
273 |
// TODO Auto-generated method stub |
|
274 |
throw new UnimplementedException(); |
|
275 |
} |
|
276 |
|
|
277 |
/** |
|
278 |
* {@inheritDoc} |
|
279 |
* |
|
280 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#registerProfile(java.lang.String) |
|
281 |
*/ |
|
282 |
@Override |
|
283 |
public String registerProfile(final String resourceProfile) throws ISRegistryException { |
|
284 |
log.debug("registering profile"); |
|
285 |
|
|
286 |
try { |
|
287 |
final OpaqueResource resource = new StringOpaqueResource(resourceProfile); |
|
288 |
|
|
289 |
// TODO: factor this out (possibly not within the OpaqueResource class) |
|
290 |
final String coll = xqueryUtils.getCollectionPath(resource); |
|
291 |
final String fileName = uuidGenerator.generateIdentifier(); |
|
292 |
final String newId = fileName + "_" + new String(Base64.encode(coll.getBytes())); |
|
293 |
resource.setResourceId(newId); |
|
294 |
|
|
295 |
resource.setModificationDate(new Date()); |
|
296 |
|
|
297 |
// log.info("validating to xml schema: " + resource.asString()); |
|
298 |
resourceValidator.validate(resource); |
|
299 |
|
|
300 |
profileValidationStrategy.accept(resource, RegistrationPhase.Register); |
|
301 |
|
|
302 |
// TODO: factor out ResourceType class |
|
303 |
isStore.insertXML(fileName, xqueryUtils.getRootCollection() + coll, resource.asString()); |
|
304 |
|
|
305 |
return resource.getResourceId(); |
|
306 |
} catch (XPathExpressionException e) { |
|
307 |
throw new ISRegistryException(e); |
|
308 |
} catch (SAXException e) { |
|
309 |
throw new ISRegistryException(e); |
|
310 |
} catch (IOException e) { |
|
311 |
throw new ISRegistryException(e); |
|
312 |
} catch (ParserConfigurationException e) { |
|
313 |
throw new ISRegistryException(e); |
|
314 |
} catch (ISStoreException e) { |
|
315 |
throw new ISRegistryException(e); |
|
316 |
} catch (ValidationException e) { |
|
317 |
throw new ISRegistryException("profile is not conforming to the schema: " + e.getMessage(), e); |
|
318 |
} |
|
319 |
} |
|
320 |
|
|
321 |
/** |
|
322 |
* {@inheritDoc} |
|
323 |
* |
|
324 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#registerSecureProfile(java.lang.String, java.lang.String) |
|
325 |
*/ |
|
326 |
@Override |
|
327 |
public String registerSecureProfile(final String resourceProfId, final String secureProfId) throws ISRegistryException { |
|
328 |
try { |
|
329 |
synchronized (this) { |
|
330 |
final String secureProfSrc; |
|
331 |
try { |
|
332 |
secureProfSrc = isLookup.getResourceProfile(secureProfId); // NOPMD |
|
333 |
} catch (ISLookUpDocumentNotFoundException e) { |
|
334 |
throw new ISRegistryException("cannot register secure profile, the given secure profile doesn't exist", e); |
|
335 |
} |
|
336 |
final OpaqueResource secureProf = new StringOpaqueResource(secureProfSrc); |
|
337 |
|
|
338 |
final String profId = validateProfile(resourceProfId); |
|
339 |
|
|
340 |
final XPath xpath = XPathFactory.newInstance().newXPath(); |
|
341 |
final Element idEl = (Element) xpath.evaluate("/RESOURCE_PROFILE/BODY/CONFIGURATION/resourceId", secureProf.asDom(), XPathConstants.NODE); |
|
342 |
idEl.setTextContent(profId); |
|
343 |
|
|
344 |
if (!updateProfile(secureProfId, secureProf.asString(), secureProf.getResourceType())) { throw new ISRegistryException( |
|
345 |
"cannot update security profile (updateProfile returned false)"); } |
|
346 |
|
|
347 |
return profId; |
|
348 |
} |
|
349 |
} catch (XPathExpressionException e) { |
|
350 |
throw new ISRegistryException(ERROR_SEC_PROFILE, e); |
|
351 |
} catch (SAXException e) { |
|
352 |
throw new ISRegistryException(ERROR_SEC_PROFILE, e); |
|
353 |
} catch (IOException e) { |
|
354 |
throw new ISRegistryException(ERROR_SEC_PROFILE, e); |
|
355 |
} catch (ParserConfigurationException e) { |
|
356 |
throw new ISRegistryException(ERROR_SEC_PROFILE, e); |
|
357 |
} catch (ISLookUpException e) { |
|
358 |
throw new ISRegistryException("cannot register secure profile, problem fetching the given secure profile", e); |
|
359 |
} |
|
360 |
} |
|
361 |
|
|
362 |
/** |
|
363 |
* {@inheritDoc} |
|
364 |
* |
|
365 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#removeProfileNode(java.lang.String, java.lang.String) |
|
366 |
*/ |
|
367 |
@Override |
|
368 |
public boolean removeProfileNode(final String profId, final String nodeId) throws ISRegistryException { |
|
369 |
// TODO Auto-generated method stub |
|
370 |
throw new UnimplementedException(); |
|
371 |
} |
|
372 |
|
|
373 |
/** |
|
374 |
* {@inheritDoc} |
|
375 |
* |
|
376 |
* @see eu.dnetlib.enabling.is.registry.rmi.ISRegistryService#replyBlackBoardMessage(java.lang.String, java.lang.String) |
|
377 |
*/ |
|
378 |
@Override |
|
379 |
public void replyBlackBoardMessage(final String profId, final String message) throws ISRegistryException { |
Also available in: Unified diff
[maven-release-plugin] copy for tag cnr-enabling-services-2.2.2