source: src/main/java/geniusweb/runserver/RunningNego.java@ 40

Last change on this file since 40 was 40, checked in by bart, 3 years ago

Refactor to help reusing partiesserver.

File size: 4.8 KB
Line 
1package geniusweb.runserver;
2
3import java.io.File;
4import java.io.IOException;
5import java.io.PrintWriter;
6import java.net.URISyntaxException;
7import java.nio.file.Path;
8import java.nio.file.Paths;
9import java.util.logging.Level;
10
11import geniusweb.events.ProtocolEvent;
12import geniusweb.protocol.CurrentNegoState;
13import geniusweb.protocol.NegoProtocol;
14import geniusweb.protocol.NegoSettings;
15import geniusweb.protocol.NegoState;
16import tudelft.utilities.logging.Reporter;
17import tudelft.utilities.repository.RepoElement;
18
19/**
20 * Contains a currently running {@link NegoProtocol}. Listens to protocol
21 * events. Kept so that we can keep track of the amount of running sessions and
22 * show progress states.
23 */
24public class RunningNego implements RepoElement<String> {
25 private static final String LOGDIRNAME = "log";
26 private static final Path logdir = getLogDir();
27 private static long negoNr = System.currentTimeMillis(); // generate unique IDs.
28
29 private final String sessionid;
30 private final transient Reporter log;
31 private final transient NegoProtocol protocol;
32 private final transient RunningNegotiationsRepo repo;
33
34 /**
35 * Create new session wth unique ID. You should call {@link #start()} to
36 * actually start this.
37 *
38 * @param settings the settings to use for this session
39 * @param repo the {@link RunningNegotiationsRepo} to use (mainly for
40 * testing)
41 * @param logger the {@link Reporter} to be used. Usually "Protocol" or
42 * "runserver". The logger is used both for logging protocol
43 * events and for logging events from this RunningNego
44 */
45 public RunningNego(NegoSettings settings, RunningNegotiationsRepo repo,
46 Reporter logger) {
47 this.log = logger;
48 this.protocol = settings.getProtocol(logger);
49 this.sessionid = "" + protocol.getRef().getURI() + (negoNr++);
50 this.repo = repo;
51 }
52
53 public void start() {
54 log.log(Level.INFO, "new negotiation session. logging to " + logdir);
55 repo.put(this);
56 protocol.addListener(evt -> handle(evt));
57 protocol.start(new PartyConnectionFactory(log));
58 }
59
60 private void handle(ProtocolEvent evt) {
61 if (evt instanceof CurrentNegoState) {
62 NegoState state = ((CurrentNegoState) evt).getState();
63 writeLogFile(state);
64 if (state.isFinal(System.currentTimeMillis())) {
65 repo.remove(sessionid);
66 }
67 }
68 }
69
70 /**
71 * Write the (final) state to the log file.
72 *
73 * @param sessionState
74 * @throws IOException
75 */
76 protected void writeLogFile(NegoState sessionState) {
77 try {
78 PrintWriter out = new PrintWriter(
79 logdir.resolve(sessionid + ".json").toFile());
80 out.print(Jackson.instance().writeValueAsString(sessionState));
81 out.close();
82 } catch (Throwable e) { // also catch outOfMem etc.
83 log.log(Level.SEVERE, "Failed to write log file for " + sessionid,
84 e);
85 }
86 }
87
88 /**
89 * Search from location of this class upwards till we find a directory
90 * called "domainsrepo".
91 *
92 * @return the root dir of the repo. This is the 'database' where all known
93 * profiles are stored. If not found , returns log dir in
94 * workingdirectory
95 * @throws URISyntaxException
96 */
97 protected static Path getLogDir() {
98 // If you run this normal from tomcat we are somewhere inside
99 // projectroot/WEB_INF/classes/....
100 // Search back upwards to projectroot.
101 Path dir;
102 try {
103 dir = Paths.get(RunningNego.class.getProtectionDomain()
104 .getCodeSource().getLocation().toURI()).getParent();
105 } catch (URISyntaxException e) {
106 throw new RuntimeException("Problem with path URI", e);
107 }
108 System.out.println("searching from " + dir);
109 while (dir.getNameCount() > 1) {
110 Path repo = dir.resolve(LOGDIRNAME);
111 if (repo.toFile().exists())
112 return repo;
113 System.out.println(
114 "Directory did not contain " + LOGDIRNAME + ":" + dir);
115 dir = dir.getParent();
116 }
117
118 // fallback to working dir
119 File file = new File(LOGDIRNAME);
120 if (!file.exists()) {
121 file.mkdir();
122 }
123 return file.toPath();
124 }
125
126 public NegoProtocol getProtocol() {
127 return protocol;
128 }
129
130 @Override
131 public String getID() {
132 return sessionid;
133 }
134
135 @Override
136 public int hashCode() {
137 final int prime = 31;
138 int result = 1;
139 result = prime * result
140 + ((protocol == null) ? 0 : protocol.hashCode());
141 result = prime * result
142 + ((sessionid == null) ? 0 : sessionid.hashCode());
143 return result;
144 }
145
146 @Override
147 public boolean equals(Object obj) {
148 if (this == obj)
149 return true;
150 if (obj == null)
151 return false;
152 if (getClass() != obj.getClass())
153 return false;
154 RunningNego other = (RunningNego) obj;
155 if (protocol == null) {
156 if (other.protocol != null)
157 return false;
158 } else if (!protocol.equals(other.protocol))
159 return false;
160 if (sessionid == null) {
161 if (other.sessionid != null)
162 return false;
163 } else if (!sessionid.equals(other.sessionid))
164 return false;
165 return true;
166 }
167
168}
Note: See TracBrowser for help on using the repository browser.