• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

leeonky / test-charm-java / 129

27 Feb 2025 03:58AM UTC coverage: 71.301% (-2.9%) from 74.244%
129

push

circleci

leeonky
Update version

6718 of 9422 relevant lines covered (71.3%)

0.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.13
/DAL-extension-inspector/src/main/java/com/github/leeonky/dal/extensions/inspector/Inspector.java
1
package com.github.leeonky.dal.extensions.inspector;
2

3
import com.github.leeonky.dal.DAL;
4
import com.github.leeonky.dal.runtime.RuntimeContextBuilder;
5
import com.github.leeonky.interpreter.InterpreterException;
6
import com.github.leeonky.util.Suppressor;
7
import io.javalin.Javalin;
8
import io.javalin.http.staticfiles.Location;
9
import io.javalin.websocket.WsContext;
10

11
import java.net.InetAddress;
12
import java.net.NetworkInterface;
13
import java.util.*;
14
import java.util.concurrent.ConcurrentHashMap;
15
import java.util.concurrent.CountDownLatch;
16
import java.util.function.Supplier;
17
import java.util.stream.Collectors;
18

19
import static com.github.leeonky.util.function.Extension.getFirstPresent;
20
import static java.util.Objects.requireNonNull;
21
import static java.util.Optional.ofNullable;
22

23
public class Inspector {
24
    private static Inspector inspector = null;
1✔
25
    private static Mode mode = null;
1✔
26
    private final Javalin javalin;
27
    private final CountDownLatch serverReadyLatch = new CountDownLatch(1);
1✔
28
    private final Set<DAL> instances = new LinkedHashSet<>();
1✔
29
    //   TODO refactor
30
    private final Map<String, WsContext> clientConnections = new ConcurrentHashMap<>();
1✔
31
    private final Map<String, Set<String>> clientMonitors = new ConcurrentHashMap<>();
1✔
32
    private final Map<String, DalInstance> dalInstances = new ConcurrentHashMap<>();
1✔
33
    private static Supplier<Object> defaultInput = () -> null;
1✔
34

35
    public Inspector() {
1✔
36
        DalInstance defaultInstance = new DalInstance(() -> defaultInput.get(), DAL.create(InspectorExtension.class), "");
1✔
37
        defaultInstance.running = false;
1✔
38
        dalInstances.put("Try It!", defaultInstance);
1✔
39
        javalin = Javalin.create(config -> config.addStaticFiles("/public", Location.CLASSPATH))
1✔
40
                .events(event -> event.serverStarted(serverReadyLatch::countDown));
1✔
41
        requireNonNull(javalin.jettyServer()).setServerPort(getServerPort());
1✔
42
        javalin.get("/", ctx -> ctx.redirect("/index.html"));
1✔
43
        javalin.post("/api/execute", ctx -> ctx.html(execute(ctx.queryParam("name"), ctx.body())));
1✔
44
        javalin.post("/api/exchange", ctx -> exchange(ctx.queryParam("session"), ctx.body()));
1✔
45
        javalin.post("/api/release", ctx -> release(ctx.queryParam("name")));
1✔
46
        javalin.post("/api/release-all", ctx -> releaseAll());
1✔
47
        javalin.get("/api/request", ctx -> ctx.html(request(ctx.queryParam("name"))));
1✔
48
        javalin.ws("/ws/exchange", ws -> {
1✔
49
            ws.onConnect(ctx -> {
1✔
50
                clientConnections.put(ctx.getSessionId(), ctx);
1✔
51
                sendInstances(ctx);
1✔
52
            });
1✔
53
            ws.onClose(ctx -> clientConnections.remove(ctx.getSessionId()));
1✔
54
        });
1✔
55
        javalin.start();
1✔
56
    }
1✔
57

58
    private void waitForReady() {
59
        Suppressor.run(serverReadyLatch::await);
1✔
60
    }
1✔
61

62
    private static int getServerPort() {
63

64
        return getFirstPresent(() -> ofNullable(System.getenv("DAL_INSPECTOR_PORT")),
1✔
65
                () -> ofNullable(System.getProperty("dal.inspector.port")))
1✔
66
                .map(Integer::parseInt)
1✔
67
                .orElse(10082);
1✔
68
    }
69

70
    public static void ready() {
71
        inspector.waitForReady();
1✔
72
    }
1✔
73

74
    private void releaseAll() {
75
        for (String instanceName : new ArrayList<>(dalInstances.keySet()))
1✔
76
            release(instanceName);
1✔
77
    }
1✔
78

79
    private void release(String name) {
80
        DalInstance remove = dalInstances.remove(name);
1✔
81
        if (remove != null)
1✔
82
            remove.release();
1✔
83
    }
1✔
84

85
    public static void setDefaultMode(Mode mode) {
86
        Inspector.mode = mode;
1✔
87
    }
1✔
88

89
    private void exchange(String session, String body) {
90
        if (clientConnections.containsKey(session)) {
1✔
91
            clientMonitors.put(session, Arrays.stream(body.trim().split("\\n")).map(String::trim).filter(s -> !s.isEmpty()).collect(Collectors.toSet()));
1✔
92

93
            for (DalInstance dalInstance : dalInstances.values()) {
1✔
94
                if (dalInstance.running)
1✔
95
                    clientConnections.get(session).send(ObjectWriter.serialize(new HashMap<String, String>() {{
1✔
96
                        put("request", dalInstance.dal.getName());
1✔
97
                    }}));
1✔
98
            }
1✔
99
        }
100
    }
1✔
101

102
    public static class DalInstance {
103
        private final Supplier<Object> input;
104
        private boolean running = true;
1✔
105
        private final DAL dal;
106
        private final String code;
107

108
        public DalInstance(Supplier<Object> input, DAL dal, String code) {
1✔
109
            this.input = input;
1✔
110
            this.dal = dal;
1✔
111
            this.code = code;
1✔
112
        }
1✔
113

114
        public String execute(String code) {
115
            Map<String, String> response = new HashMap<>();
1✔
116
            Object inputObject = input.get();
1✔
117
            RuntimeContextBuilder.DALRuntimeContext runtimeContext = dal.getRuntimeContextBuilder().build(inputObject);
1✔
118
            try {
119
                response.put("root", runtimeContext.wrap(inputObject).dumpAll());
1✔
120
                response.put("inspect", dal.compileSingle(code, runtimeContext).inspect());
1✔
121
                response.put("result", runtimeContext.wrap(dal.evaluate(inputObject, code)).dumpAll());
1✔
122
            } catch (InterpreterException e) {
1✔
123
                response.put("error", e.show(code) + "\n\n" + e.getMessage());
1✔
124
            }
1✔
125
            return ObjectWriter.serialize(response);
1✔
126
        }
127

128
        public void hold() {
129
            System.err.println("Waiting for DAL inspector release...");
1✔
130
            try {
131
                Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
1✔
132

133
                System.err.println("\tDal inspector running at:");
1✔
134

135
                while (interfaces.hasMoreElements()) {
1✔
136
                    Enumeration<InetAddress> inetAddresses = interfaces.nextElement().getInetAddresses();
1✔
137
                    while (inetAddresses.hasMoreElements()) {
1✔
138
                        InetAddress address = inetAddresses.nextElement();
1✔
139
                        System.err.printf("\t\thttp://%s:%d%n", address.getHostAddress(), getServerPort());
1✔
140
                    }
1✔
141
                }
1✔
142
            } catch (Exception ignore) {
×
143
            }
1✔
144
            //        TODO use sempahore to wait for the result
145
            while (running)
1✔
146
                Suppressor.run(() -> Thread.sleep(20));
1✔
147
//            TODO use logger
148
            System.err.println("DAL inspector released");
1✔
149
        }
1✔
150

151
        public void release() {
152
            running = false;
1✔
153
        }
1✔
154
    }
155

156
    public void inspectInner(DAL dal, Object input, String code) {
157
        if (isRecursive())
1✔
158
            return;
1✔
159
//        lock inspect by name
160
//        check mode
161
        if (currentMode() == Mode.FORCED) {
1✔
162
            DalInstance dalInstance = new DalInstance(() -> input, dal, code);
1✔
163
            dalInstances.put(dal.getName(), dalInstance);
1✔
164

165
//            List<WsContext> monitored = clientMonitors.entrySet().stream().filter(e -> e.getValue().contains(dal.getName()))
166
//                    .map(o -> clientConnections.get(o.getKey()))
167
//                    .collect(Collectors.toList());
168
//            TODO check monitor flag
169
            for (WsContext wsContext : clientConnections.values()) {
1✔
170
                wsContext.send(ObjectWriter.serialize(new HashMap<String, String>() {{
1✔
171
                    put("request", dal.getName());
1✔
172
                }}));
1✔
173
            }
1✔
174

175
            dalInstance.hold();
1✔
176

177
        } else {
1✔
178
//        TODO refactor
179
            List<WsContext> monitored = clientMonitors.entrySet().stream().filter(e -> e.getValue().contains(dal.getName()))
1✔
180
                    .map(o -> clientConnections.get(o.getKey()))
1✔
181
                    .collect(Collectors.toList());
1✔
182
            if (!monitored.isEmpty()) {
1✔
183
                DalInstance dalInstance = new DalInstance(() -> input, dal, code);
1✔
184
                dalInstances.put(dal.getName(), dalInstance);
1✔
185
                for (WsContext wsContext : monitored) {
1✔
186
                    wsContext.send(ObjectWriter.serialize(new HashMap<String, String>() {{
1✔
187
                        put("request", dal.getName());
1✔
188
                    }}));
1✔
189
                }
1✔
190

191
                dalInstance.hold();
×
192
            }
193
        }
194
    }
1✔
195

196
    public static void inspect(DAL dal, Object input, String code) {
197
        if (currentMode() != Mode.DISABLED)
1✔
198
            inspector.inspectInner(dal, input, code);
1✔
199
    }
1✔
200

201
    private String request(String name) {
202
//       TODO reject other request
203
        return dalInstances.get(name).code;
1✔
204
    }
205

206
    private String execute(String name, String code) {
207
        return dalInstances.get(name).execute(code);
1✔
208
    }
209

210
    public static void register(DAL dal) {
211
        inspector.addInstance(dal);
1✔
212
    }
1✔
213

214
    private void addInstance(DAL dal) {
215
        instances.add(dal);
1✔
216
        for (WsContext ctx : clientConnections.values()) {
1✔
217
            sendInstances(ctx);
1✔
218
        }
1✔
219
    }
1✔
220

221
    private void sendInstances(WsContext ctx) {
222
        ctx.send(ObjectWriter.serialize(new HashMap<String, Object>() {{
1✔
223
            put("instances", instances.stream().map(DAL::getName).collect(Collectors.toSet()));
1✔
224
            put("session", ctx.getSessionId());
1✔
225
        }}));
1✔
226
    }
1✔
227

228
    private void stop() {
229
        javalin.close();
1✔
230
    }
1✔
231

232
    public static void launch() {
233
        if (inspector == null) {
1✔
234
            inspector = new Inspector();
1✔
235
        }
236
    }
1✔
237

238
    public static void shutdown() {
239
        if (inspector != null) {
1✔
240
            inspector.stop();
1✔
241
            inspector = null;
1✔
242
        }
243
    }
1✔
244

245
    public static void setDefaultInput(Supplier<Object> supplier) {
246
        defaultInput = supplier;
1✔
247
    }
1✔
248

249
    public static Mode currentMode() {
250
        return getFirstPresent(() -> ofNullable(mode),
1✔
251
                () -> ofNullable(System.getenv("DAL_INSPECTOR_MODE")).map(Mode::valueOf),
×
252
                () -> ofNullable(System.getProperty("dal.inspector.mode")).map(Mode::valueOf))
×
253
                .orElse(Mode.DISABLED);
1✔
254
    }
255

256
    public enum Mode {
1✔
257
        DISABLED, FORCED, AUTO
1✔
258
    }
259

260
    private boolean isRecursive() {
261
        for (StackTraceElement stack : Thread.currentThread().getStackTrace())
1✔
262
            if (DalInstance.class.getName().equals(stack.getClassName()))
1✔
263
                return true;
1✔
264
        return false;
1✔
265
    }
266

267
    public static void main(String[] args) {
268
        launch();
×
269
    }
×
270
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc