Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8f7b26d
implement job manager for webapp.
cloverhearts May 9, 2016
2fb5f7a
implement logic web for jobmanger.
cloverhearts May 10, 2016
d23fb7b
add notebook filter in jab manager page
cloverhearts May 11, 2016
f51baaa
Merge branch 'master' into feat/jobmanagement
cloverhearts May 18, 2016
7b4db8d
add sort to job item
cloverhearts May 18, 2016
b24b4e7
add momentjs in .jshintrc
cloverhearts May 19, 2016
b90e320
implement notebook job management backend.
cloverhearts May 24, 2016
35887c0
Implement cs transition for jobmanagement.
cloverhearts May 26, 2016
5b20b03
Merge branch 'master' into feat/jobmanagement
cloverhearts May 26, 2016
f87217c
improve jobmanagement ui and timestamp
cloverhearts May 26, 2016
f1296a8
bug fixed and improve run status to always top for job manager page.
cloverhearts May 27, 2016
75c03ef
remove semicolon for job manager
cloverhearts May 27, 2016
f3575f9
Merge branch 'master' into feat/jobmanagement
cloverhearts May 27, 2016
0bcb9ff
Additional feedback in the absence of the interpreter for jobmanager
cloverhearts May 30, 2016
4695c64
Merge branch 'master' into ZEPPELIN-531
cloverhearts May 30, 2016
877b203
optimize job management - slow down issue.
cloverhearts May 30, 2016
5a78136
add comment and change variable name.
cloverhearts May 31, 2016
caf4f31
was divided zeppelin-notebook server - job manager server.
cloverhearts May 31, 2016
a949015
refactor job manager
cloverhearts Jun 1, 2016
3878de3
modifed test case and WebSocket server class extends structure changes
cloverhearts Jun 1, 2016
80165f5
add 'check undefined logic' in jobmanager.controller
cloverhearts Jun 1, 2016
2d37f89
implement observer in notebook
cloverhearts Jun 2, 2016
86bd17c
changed observer noti in note class
cloverhearts Jun 2, 2016
a40c734
job manager bug fix and improve
cloverhearts Jun 3, 2016
9e227fc
Merge branch 'master' into ZEPPELIN-531
cloverhearts Jun 3, 2016
97e8bbe
remove class job manager server
cloverhearts Jun 4, 2016
d3c40ec
remove notebook target op for job manager
cloverhearts Jun 4, 2016
ab1fecd
Merge branch 'master' into ZEPPELIN-531
cloverhearts Jun 4, 2016
7960e28
changed ui - filter, select, and button size - job manager
cloverhearts Jun 4, 2016
9e8e584
Merge branch 'master' into ZEPPELIN-531
cloverhearts Jun 4, 2016
5590b66
remove bin/derby.log
cloverhearts Jun 4, 2016
bc443da
remove head tag - job manager.
cloverhearts Jun 4, 2016
49422f0
Merge branch 'master' into ZEPPELIN-531
cloverhearts Jun 6, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import javax.ws.rs.core.Response.Status;

import org.apache.commons.lang3.StringUtils;
import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.annotation.ZeppelinApi;
import org.apache.zeppelin.interpreter.InterpreterSetting;
import org.apache.zeppelin.notebook.Note;
Expand All @@ -54,9 +55,7 @@
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
import java.io.StringReader;

/**
* Rest api endpoint for the noteBook.
*/
Expand Down Expand Up @@ -489,8 +488,13 @@ public Response runNoteJobs(@PathParam("notebookId") String notebookId) throws
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}

note.runAll();
try {
note.runAll();
} catch (InterpreterException intpException) {
return new JsonResponse<>(Status.INTERNAL_SERVER_ERROR, intpException.getMessage()).build();
} catch (Exception e) {
return new JsonResponse<>(Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference in handling this 2 exceptional conditions?

}
return new JsonResponse<>(Status.OK).build();
}

Expand All @@ -511,10 +515,14 @@ public Response stopNoteJobs(@PathParam("notebookId") String notebookId) throws
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}

for (Paragraph p : note.getParagraphs()) {
if (!p.isTerminated()) {
p.abort();
try {
for (Paragraph p : note.getParagraphs()) {
if (!p.isTerminated()) {
p.abort();
}
}
} catch (Exception e) {
return new JsonResponse<>(Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
}
return new JsonResponse<>(Status.OK).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.zeppelin.scheduler.SchedulerFactory;
import org.apache.zeppelin.search.LuceneSearch;
import org.apache.zeppelin.search.SearchService;
import org.apache.zeppelin.socket.AppMainServer;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it used later in this class?

import org.apache.zeppelin.socket.NotebookServer;
import org.apache.zeppelin.user.Credentials;
import org.eclipse.jetty.http.HttpVersion;
Expand Down Expand Up @@ -104,8 +105,8 @@ public static void main(String[] args) throws InterruptedException {
// REST api
setupRestApiContextHandler(webApp, conf);

// Notebook server
setupNotebookServer(webApp, conf);
// Main Notebook WS server
notebookWsServer = setupNotebookServer(webApp, conf);

//Below is commented since zeppelin-docs module is removed.
//final WebAppContext webAppSwagg = setupWebAppSwagger(conf);
Expand All @@ -119,6 +120,9 @@ public static void main(String[] args) throws InterruptedException {
}
LOG.info("Done, zeppelin server started");

// register observer for job manager.
notebook.getNotebookEventObserver().addObserver(notebookWsServer);

Runtime.getRuntime().addShutdownHook(new Thread(){
@Override public void run() {
LOG.info("Shutting down Zeppelin Server ... ");
Expand Down Expand Up @@ -192,17 +196,16 @@ private static Server setupJettyServer(ZeppelinConfiguration conf) {
return server;
}

private static void setupNotebookServer(WebAppContext webapp,
ZeppelinConfiguration conf) {
notebookWsServer = new NotebookServer();
private static NotebookServer setupNotebookServer(WebAppContext webapp,
ZeppelinConfiguration conf) {
NotebookServer notebookWsServer = new NotebookServer();
String maxTextMessageSize = conf.getWebsocketMaxTextMessageSize();
final ServletHolder servletHolder = new ServletHolder(notebookWsServer);
servletHolder.setInitParameter("maxTextMessageSize", maxTextMessageSize);

final ServletContextHandler cxfContext = new ServletContextHandler(
ServletContextHandler.SESSIONS);

ServletContextHandler.SESSIONS);
webapp.addServlet(servletHolder, "/ws/*");
return notebookWsServer;
}

private static SslContextFactory getSslContextFactory(ZeppelinConfiguration conf) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.zeppelin.socket;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.servlet.http.HttpServletRequest;

import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import org.apache.zeppelin.conf.ZeppelinConfiguration;
import org.apache.zeppelin.notebook.socket.Message;
import org.apache.zeppelin.ticket.TicketContainer;
import org.apache.zeppelin.utils.SecurityUtils;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Zeppelin websocket service.
*/
public class AppMainServer extends WebSocketServlet implements
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please help me to understand what doesAppMain mean in this class name? Will there be other apps, and this is somehow a main one?

Descriptive names usually aid code maintainability, so how do you think, may be re-nameing it to something along JavaDoc comment, like ZeppelinWebsocketServer would make sense?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bzz
Inheritance is a servlet of the web applications possible.
I determined that conventional NotebookServer classes could be expanded.
For example, Workflow server.
i would be improve document and renaming.

WebSocketListener, WebSocketServer {
private static final Logger LOG = LoggerFactory.getLogger(AppMainServer.class);
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create();

final Map<String, WebSocketServer> subWebSocketServer = new HashMap<>();

final Map<String, List<WebAppSocket>> userWebSocketMap = new HashMap<>();
final Queue<WebAppSocket> connectedSockets = new ConcurrentLinkedQueue<>();


@Override
public void configure(WebSocketServletFactory factory) {
factory.setCreator(new WebAppSocketCreator(this));
}

public boolean checkOrigin(HttpServletRequest request, String origin) {
try {
return SecurityUtils.isValidOrigin(origin, ZeppelinConfiguration.create());
} catch (UnknownHostException e) {
LOG.error(e.toString(), e);
} catch (URISyntaxException e) {
LOG.error(e.toString(), e);
}
return false;
}

public WebAppSocket doWebSocketConnect(HttpServletRequest req, String protocol) {
return new WebAppSocket(req, protocol, this);
}

public void setSubWebSocketServer(String key, WebSocketServer server) {
synchronized (subWebSocketServer) {
subWebSocketServer.remove(key);
subWebSocketServer.put(key, server);
}
}

@Override
public void onOpen(WebAppSocket conn) {
LOG.info("New connection from {} : {}", conn.getRequest().getRemoteAddr(),
conn.getRequest().getRemotePort());
connectedSockets.add(conn);
}

@Override
public void onMessage(WebAppSocket conn, String msg) {
try {
Message messagereceived = deserializeMessage(msg);
LOG.debug("RECEIVE << " + messagereceived.op);
LOG.debug("RECEIVE PRINCIPAL << " + messagereceived.principal);
LOG.debug("RECEIVE TICKET << " + messagereceived.ticket);
LOG.debug("RECEIVE ROLES << " + messagereceived.roles);

if (LOG.isTraceEnabled()) {
LOG.trace("RECEIVE MSG = " + messagereceived);
}

WebSocketServer processServer = subWebSocketServer.get(messagereceived.target);
if (processServer != null) {
LOG.debug("server {} received.", messagereceived.target);
processServer.onMessage(conn, msg);
} else {
LOG.debug("server {} received.", AppMainServer.class.toString());
}

/** Lets be elegant here */
switch (messagereceived.op) {
case PING:
break; //do nothing
default:
break;
}
} catch (Exception e) {
LOG.error("Can't handle message", e);
}
}

@Override
public void onClose(WebAppSocket conn, int code, String reason) {
LOG.info("Closed connection to {} : {}. ({}) {}", conn.getRequest()
.getRemoteAddr(), conn.getRequest().getRemotePort(), code, reason);
removeConnectionFromAllKey(conn);
connectedSockets.remove(conn);
}

protected Message deserializeMessage(String msg) {
return gson.fromJson(msg, Message.class);
}

protected String serializeMessage(Message m) {
return gson.toJson(m);
}

protected void addConnectionToKey(String key, WebAppSocket socket) {
synchronized (userWebSocketMap) {
removeConnectionFromAllKey(socket); // make sure a socket relates only a
// single key.
List<WebAppSocket> socketList = userWebSocketMap.get(key);
if (socketList == null) {
socketList = new LinkedList<>();
userWebSocketMap.put(key, socketList);
}
if (!socketList.contains(socket)) {
socketList.add(socket);
}
}
}

protected void removeConnectionFromKey(String key, WebAppSocket socket) {
synchronized (userWebSocketMap) {
List<WebAppSocket> socketList = userWebSocketMap.get(key);
if (socketList != null) {
socketList.remove(socket);
}
}
}

protected void removeKey(String key) {
synchronized (userWebSocketMap) {
List<WebAppSocket> socketList = userWebSocketMap.remove(key);
}
}

protected void removeConnectionFromAllKey(WebAppSocket socket) {
synchronized (userWebSocketMap) {
Set<String> keys = userWebSocketMap.keySet();
for (String keyValue : keys) {
removeConnectionFromKey(keyValue, socket);
}
}
}

protected String getOpenKey(WebAppSocket socket) {
String key = null;
synchronized (userWebSocketMap) {
Set<String> keys = userWebSocketMap.keySet();
for (String keyValue : keys) {
List<WebAppSocket> sockets = userWebSocketMap.get(keyValue);
if (sockets.contains(socket)) {
key = keyValue;
}
}
}

return key;
}

protected void broadcast(String key, Message m) {
synchronized (userWebSocketMap) {
List<WebAppSocket> socketLists = userWebSocketMap.get(key);
if (socketLists == null || socketLists.size() == 0) {
return;
}
LOG.debug("SEND >> " + m.op);
for (WebAppSocket conn : socketLists) {
try {
conn.send(serializeMessage(m));
} catch (IOException e) {
LOG.error("socket error", e);
removeConnectionFromAllKey(conn);
}
}
}
}

protected void broadcastExcept(String key, Message m, WebAppSocket exclude) {
synchronized (userWebSocketMap) {
List<WebAppSocket> socketLists = userWebSocketMap.get(key);
if (socketLists == null || socketLists.size() == 0) {
return;
}
LOG.debug("SEND >> " + m.op);
for (WebAppSocket conn : socketLists) {
if (exclude.equals(conn)) {
continue;
}
try {
conn.send(serializeMessage(m));
} catch (IOException e) {
LOG.error("socket error", e);
}
}
}
}

protected void broadcastAll(Message m) {
for (WebAppSocket conn : connectedSockets) {
try {
conn.send(serializeMessage(m));
} catch (IOException e) {
LOG.error("socket error", e);
}
}
}

protected void unicast(Message m, WebAppSocket conn) {
try {
conn.send(serializeMessage(m));
} catch (IOException e) {
LOG.error("socket error", e);
}
}
}

Loading