|
|
|
@ -9,6 +9,10 @@ import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Objects;
|
|
|
|
|
import java.util.Optional;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.PostConstruct;
|
|
|
|
|
|
|
|
|
|
import org.apache.commons.io.IOUtils;
|
|
|
|
|
import org.apache.commons.lang.StringEscapeUtils;
|
|
|
|
@ -18,6 +22,7 @@ import org.apache.commons.logging.LogFactory;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
import org.springframework.http.HttpEntity;
|
|
|
|
|
import org.springframework.http.HttpHeaders;
|
|
|
|
|
import org.springframework.http.HttpMethod;
|
|
|
|
|
import org.springframework.http.HttpStatus;
|
|
|
|
|
import org.springframework.http.MediaType;
|
|
|
|
|
import org.springframework.http.ResponseEntity;
|
|
|
|
@ -27,9 +32,11 @@ import org.springframework.util.MultiValueMap;
|
|
|
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
|
|
|
|
|
|
|
import eu.dnetlib.data.mdstore.manager.exceptions.MDStoreManagerException;
|
|
|
|
|
import eu.dnetlib.data.mdstore.manager.utils.zeppelin.HasStatus;
|
|
|
|
|
import eu.dnetlib.data.mdstore.manager.utils.zeppelin.ListResponse;
|
|
|
|
|
import eu.dnetlib.data.mdstore.manager.utils.zeppelin.Note;
|
|
|
|
|
import eu.dnetlib.data.mdstore.manager.utils.zeppelin.Paragraph;
|
|
|
|
|
import eu.dnetlib.data.mdstore.manager.utils.zeppelin.SimpleResponse;
|
|
|
|
|
import eu.dnetlib.data.mdstore.manager.utils.zeppelin.StringResponse;
|
|
|
|
|
import eu.dnetlib.dhp.schema.mdstore.MDStoreWithInfo;
|
|
|
|
|
|
|
|
|
@ -50,16 +57,27 @@ public class ZeppelinClient {
|
|
|
|
|
|
|
|
|
|
private static final Log log = LogFactory.getLog(ZeppelinClient.class);
|
|
|
|
|
|
|
|
|
|
private static final Map<String, List<String>> DEFAULT_RIGHTS = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
|
|
@PostConstruct
|
|
|
|
|
public void init() {
|
|
|
|
|
DEFAULT_RIGHTS.put("owners", Arrays.asList(zeppelinLogin));
|
|
|
|
|
DEFAULT_RIGHTS.put("readers", new ArrayList<>()); // ALL
|
|
|
|
|
DEFAULT_RIGHTS.put("runners", new ArrayList<>()); // ALL
|
|
|
|
|
DEFAULT_RIGHTS.put("writers", new ArrayList<>()); // ALL
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String jsessionid;
|
|
|
|
|
|
|
|
|
|
public String zeppelinNote(final String note, final MDStoreWithInfo mdstore, final String currentVersionPath) throws MDStoreManagerException {
|
|
|
|
|
final String jsessionid = obtainJsessionID();
|
|
|
|
|
|
|
|
|
|
final String newName =
|
|
|
|
|
StringUtils.join(Arrays.asList(zeppelinNamePrefix, "notes", mdstore.getDatasourceName().replaceAll("/", "-"), mdstore.getApiId()
|
|
|
|
|
.replaceAll("/", "-"), note.replaceAll("/", "-"), mdstore.getCurrentVersion().replaceAll("/", "-")), "/");
|
|
|
|
|
|
|
|
|
|
final Optional<String> oldNoteId = listNotes(jsessionid).stream()
|
|
|
|
|
final List<Map<String, String>> notes = listNotes();
|
|
|
|
|
|
|
|
|
|
final Optional<String> oldNoteId = notes.stream()
|
|
|
|
|
.filter(Objects::nonNull)
|
|
|
|
|
.filter(map -> newName.equals(map.get("name")))
|
|
|
|
|
.map(map -> map.get("id"))
|
|
|
|
@ -70,140 +88,43 @@ public class ZeppelinClient {
|
|
|
|
|
return zeppelinBaseUrl + "/#/notebook/" + oldNoteId.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final String templateNoteId = findTemplateNoteId(note, jsessionid);
|
|
|
|
|
final String templateName = zeppelinNamePrefix + "/templates/" + note;
|
|
|
|
|
final String templateNoteId = notes.stream()
|
|
|
|
|
.filter(map -> map.get("name").equals(templateName))
|
|
|
|
|
.map(map -> map.get("id"))
|
|
|
|
|
.findFirst()
|
|
|
|
|
.orElseThrow(() -> new MDStoreManagerException("Template Note not found: " + templateName));
|
|
|
|
|
|
|
|
|
|
final String newId = cloneNote(templateNoteId, newName, jsessionid);
|
|
|
|
|
|
|
|
|
|
log.info("New note created, id: " + newId + ", name: " + newName);
|
|
|
|
|
|
|
|
|
|
addParagraph(newId, confParagraph(mdstore, currentVersionPath), jsessionid);
|
|
|
|
|
|
|
|
|
|
reassignRights(newId, jsessionid);
|
|
|
|
|
final String newId = cloneNote(templateNoteId, newName, mdstore, currentVersionPath);
|
|
|
|
|
|
|
|
|
|
return zeppelinBaseUrl + "/#/notebook/" + newId;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: prepare the cron job
|
|
|
|
|
public void cleanExpiredNotes() {
|
|
|
|
|
try {
|
|
|
|
|
final String jsessionid = obtainJsessionID();
|
|
|
|
|
|
|
|
|
|
for (final Map<String, String> n : listNotes(jsessionid)) {
|
|
|
|
|
final String id = n.get("id");
|
|
|
|
|
if (n.get("name").startsWith(zeppelinNamePrefix + "/notes/") && isExpired(id, jsessionid)) {
|
|
|
|
|
deleteNote(id, jsessionid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (final Exception e) {
|
|
|
|
|
log.error("Error cleaning expired notes", e);
|
|
|
|
|
}
|
|
|
|
|
public List<String> listTemplates() {
|
|
|
|
|
final String prefix = zeppelinNamePrefix + "/templates/";
|
|
|
|
|
return listNotes().stream()
|
|
|
|
|
.map(map -> map.get("name"))
|
|
|
|
|
.filter(s -> s.startsWith(prefix))
|
|
|
|
|
.map(s -> StringUtils.substringAfter(s, prefix))
|
|
|
|
|
.sorted()
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String obtainJsessionID() throws MDStoreManagerException {
|
|
|
|
|
|
|
|
|
|
final HttpHeaders headers = new HttpHeaders();
|
|
|
|
|
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
|
|
|
|
|
|
|
|
|
final MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
|
|
|
|
map.add("userName", zeppelinLogin);
|
|
|
|
|
map.add("password", zeppelinPassword);
|
|
|
|
|
final HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
|
|
|
|
|
|
|
|
|
|
final String url = zeppelinBaseUrl + "/api/login";
|
|
|
|
|
final ResponseEntity<?> res = new RestTemplate().postForEntity(url, request, Object.class);
|
|
|
|
|
|
|
|
|
|
if (res.getStatusCode() != HttpStatus.OK) {
|
|
|
|
|
log.error("Zeppelin API: login failed with HTTP error: " + res);
|
|
|
|
|
throw new MDStoreManagerException("Zeppelin API: login failed with HTTP error: " + res);
|
|
|
|
|
} else if (!res.getHeaders().containsKey(HttpHeaders.SET_COOKIE)) {
|
|
|
|
|
log.error("Zeppelin API: login failed (missing SET_COOKIE header)");
|
|
|
|
|
throw new MDStoreManagerException("Zeppelin API: login failed (missing SET_COOKIE header)");
|
|
|
|
|
} else {
|
|
|
|
|
return res.getHeaders()
|
|
|
|
|
.get(HttpHeaders.SET_COOKIE)
|
|
|
|
|
.stream()
|
|
|
|
|
.map(s -> s.split(";"))
|
|
|
|
|
.flatMap(Arrays::stream)
|
|
|
|
|
.map(String::trim)
|
|
|
|
|
.filter(s -> s.startsWith("JSESSIONID="))
|
|
|
|
|
.map(s -> StringUtils.removeStart(s, "JSESSIONID="))
|
|
|
|
|
.filter(s -> !s.equalsIgnoreCase("deleteMe"))
|
|
|
|
|
.distinct()
|
|
|
|
|
.filter(this::testConnection)
|
|
|
|
|
.findFirst()
|
|
|
|
|
.orElseThrow(() -> new MDStoreManagerException("Zeppelin API: login failed (invalid jsessionid)"));
|
|
|
|
|
}
|
|
|
|
|
private List<Map<String, String>> listNotes() {
|
|
|
|
|
return callApi(HttpMethod.GET, "notebook", ListResponse.class, null).getBody();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean testConnection(final String jsessionid) {
|
|
|
|
|
private String cloneNote(final String noteId, final String newName, final MDStoreWithInfo mdstore, final String currentVersionPath)
|
|
|
|
|
throws MDStoreManagerException {
|
|
|
|
|
final String newId = callApi(HttpMethod.POST, "notebook/" + noteId, StringResponse.class, new Note(newName)).getBody();
|
|
|
|
|
callApi(HttpMethod.POST, "notebook/" + noteId + "/paragraph", StringResponse.class, confParagraph(mdstore, currentVersionPath)).getBody();
|
|
|
|
|
callApi(HttpMethod.PUT, "notebook/" + noteId + "/permissions", SimpleResponse.class, DEFAULT_RIGHTS);
|
|
|
|
|
|
|
|
|
|
final String url = zeppelinBaseUrl + "/api/notebook;JSESSIONID=" + jsessionid;
|
|
|
|
|
log.info("Performing GET: " + url);
|
|
|
|
|
log.info("New note created, id: " + newId + ", name: " + newName);
|
|
|
|
|
|
|
|
|
|
final ResponseEntity<ListResponse> res = new RestTemplate().getForEntity(url, ListResponse.class);
|
|
|
|
|
return newId;
|
|
|
|
|
|
|
|
|
|
if (res.getStatusCode() != HttpStatus.OK) {
|
|
|
|
|
return false;
|
|
|
|
|
} else if (res.getBody() == null) {
|
|
|
|
|
return false;
|
|
|
|
|
} else if (!res.getBody().getStatus().equals("OK")) {
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
log.info("Connected to zeppelin: " + res.getBody());
|
|
|
|
|
log.info("Found JSESSIONID: " + jsessionid);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<Map<String, String>> listNotes(final String jsessionid) throws MDStoreManagerException {
|
|
|
|
|
final String url = zeppelinBaseUrl + "/api/notebook;JSESSIONID=" + jsessionid;
|
|
|
|
|
log.info("Performing GET: " + url);
|
|
|
|
|
|
|
|
|
|
final ResponseEntity<ListResponse> res = new RestTemplate().getForEntity(url, ListResponse.class);
|
|
|
|
|
|
|
|
|
|
if (res.getStatusCode() != HttpStatus.OK) {
|
|
|
|
|
log.error("Zeppelin API failed with HTTP error: " + res);
|
|
|
|
|
throw new MDStoreManagerException("Zeppelin API failed with HTTP error: " + res);
|
|
|
|
|
} else if (res.getBody() == null) {
|
|
|
|
|
log.error("Zeppelin API returned a null response");
|
|
|
|
|
throw new MDStoreManagerException("Zeppelin API returned a null response");
|
|
|
|
|
} else if (!res.getBody().getStatus().equals("OK")) {
|
|
|
|
|
log.error("Registration of zeppelin note failed: " + res.getBody());
|
|
|
|
|
throw new MDStoreManagerException("Registration of zeppelin note failed: " + res.getBody());
|
|
|
|
|
} else {
|
|
|
|
|
return res.getBody().getBody();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String findTemplateNoteId(final String noteTemplate, final String jsessionid) throws MDStoreManagerException {
|
|
|
|
|
final String templateName = zeppelinNamePrefix + "/templates/" + noteTemplate;
|
|
|
|
|
|
|
|
|
|
return listNotes(jsessionid).stream()
|
|
|
|
|
.filter(map -> map.get("name").equals(templateName))
|
|
|
|
|
.map(map -> map.get("id"))
|
|
|
|
|
.findFirst()
|
|
|
|
|
.orElseThrow(() -> new MDStoreManagerException("Template Note not found: " + templateName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String cloneNote(final String noteId, final String newName, final String jsessionid) throws MDStoreManagerException {
|
|
|
|
|
final String url = zeppelinBaseUrl + "/api/notebook/" + noteId + ";JSESSIONID=" + jsessionid;
|
|
|
|
|
log.debug("Performing POST: " + url);
|
|
|
|
|
|
|
|
|
|
final ResponseEntity<StringResponse> res = new RestTemplate().postForEntity(url, new Note(newName), StringResponse.class);
|
|
|
|
|
|
|
|
|
|
if (res.getStatusCode() != HttpStatus.OK) {
|
|
|
|
|
log.error("Zeppelin API failed with HTTP error: " + res);
|
|
|
|
|
throw new MDStoreManagerException("Zeppelin API failed with HTTP error: " + res);
|
|
|
|
|
} else if (res.getBody() == null) {
|
|
|
|
|
log.error("Zeppelin API returned a null response");
|
|
|
|
|
throw new MDStoreManagerException("Zeppelin API returned a null response");
|
|
|
|
|
} else if (!res.getBody().getStatus().equals("OK")) {
|
|
|
|
|
log.error("Registration of zeppelin note failed: " + res.getBody());
|
|
|
|
|
throw new MDStoreManagerException("Registration of zeppelin note failed: " + res.getBody());
|
|
|
|
|
} else {
|
|
|
|
|
return res.getBody().getBody();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Paragraph confParagraph(final MDStoreWithInfo mdstore, final String currentVersionPath) throws MDStoreManagerException {
|
|
|
|
@ -222,48 +143,143 @@ public class ZeppelinClient {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String addParagraph(final String noteId, final Paragraph paragraph, final String jsessionid) throws MDStoreManagerException {
|
|
|
|
|
final String url = zeppelinBaseUrl + "/api/notebook/" + noteId + "/paragraph;JSESSIONID=" + jsessionid;
|
|
|
|
|
log.debug("Performing POST: " + url);
|
|
|
|
|
// TODO: prepare the cron job
|
|
|
|
|
public void cleanExpiredNotes() {
|
|
|
|
|
try {
|
|
|
|
|
for (final Map<String, String> n : listNotes()) {
|
|
|
|
|
final String id = n.get("id");
|
|
|
|
|
if (n.get("name").startsWith(zeppelinNamePrefix + "/notes/") && isExpired(id)) {
|
|
|
|
|
deleteNote(id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (final Exception e) {
|
|
|
|
|
log.error("Error cleaning expired notes", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final ResponseEntity<StringResponse> res = new RestTemplate().postForEntity(url, paragraph, StringResponse.class);
|
|
|
|
|
private void deleteNote(final String noteId) {
|
|
|
|
|
callApi(HttpMethod.DELETE, "notebook/" + noteId, SimpleResponse.class, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (res.getStatusCode() != HttpStatus.OK) {
|
|
|
|
|
private boolean isExpired(final String id) {
|
|
|
|
|
// TODO Auto-generated method stub
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private <T extends HasStatus> T callApi(final HttpMethod method, final String api, final Class<T> resClazz, final Object objRequest) {
|
|
|
|
|
|
|
|
|
|
if (jsessionid == null) {
|
|
|
|
|
final T res = findNewJsessionId(method, api, resClazz, objRequest);
|
|
|
|
|
if (res != null) { return res; }
|
|
|
|
|
} else {
|
|
|
|
|
try {
|
|
|
|
|
return callApi(method, api, resClazz, objRequest, jsessionid);
|
|
|
|
|
} catch (final MDStoreManagerException e) {
|
|
|
|
|
final T res = findNewJsessionId(method, api, resClazz, objRequest);
|
|
|
|
|
if (res != null) { return res; }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
throw new RuntimeException("All attempted calls are failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
private <T extends HasStatus> T callApi(final HttpMethod method,
|
|
|
|
|
final String api,
|
|
|
|
|
final Class<T> resClazz,
|
|
|
|
|
final Object objRequest,
|
|
|
|
|
final String jsessionid)
|
|
|
|
|
throws MDStoreManagerException {
|
|
|
|
|
final String url = String.format("%s/api/%s;JSESSIONID=%s", zeppelinBaseUrl, api, jsessionid);
|
|
|
|
|
|
|
|
|
|
final RestTemplate restTemplate = new RestTemplate();
|
|
|
|
|
|
|
|
|
|
ResponseEntity<T> res = null;
|
|
|
|
|
|
|
|
|
|
switch (method) {
|
|
|
|
|
case GET:
|
|
|
|
|
log.info("Performing GET: " + url);
|
|
|
|
|
res = restTemplate.getForEntity(url, resClazz);
|
|
|
|
|
break;
|
|
|
|
|
case POST:
|
|
|
|
|
log.info("Performing POST: " + url);
|
|
|
|
|
res = restTemplate.postForEntity(url, objRequest, resClazz);
|
|
|
|
|
break;
|
|
|
|
|
case PUT:
|
|
|
|
|
log.info("Performing PUT: " + url);
|
|
|
|
|
restTemplate.put(url, objRequest);
|
|
|
|
|
break;
|
|
|
|
|
case DELETE:
|
|
|
|
|
log.info("Performing DELETE: " + url);
|
|
|
|
|
restTemplate.delete(url);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
throw new RuntimeException("Unsupported method: " + method);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (method == HttpMethod.PUT || method == HttpMethod.DELETE) {
|
|
|
|
|
return (T) new SimpleResponse("OK");
|
|
|
|
|
} else if (res == null) {
|
|
|
|
|
log.error("NULL response from the API");
|
|
|
|
|
throw new MDStoreManagerException("NULL response from the API");
|
|
|
|
|
} else if (res.getStatusCode() != HttpStatus.OK) {
|
|
|
|
|
log.error("Zeppelin API failed with HTTP error: " + res);
|
|
|
|
|
throw new MDStoreManagerException("Zeppelin API failed with HTTP error: " + res);
|
|
|
|
|
} else if (res.getBody() == null) {
|
|
|
|
|
log.error("Zeppelin API returned a null response");
|
|
|
|
|
throw new MDStoreManagerException("Zeppelin API returned a null response");
|
|
|
|
|
} else if (!res.getBody().getStatus().equals("OK")) {
|
|
|
|
|
log.error("Registration of zeppelin note failed: " + res.getBody());
|
|
|
|
|
log.error("Zeppelin API Operation failed: " + res.getBody());
|
|
|
|
|
throw new MDStoreManagerException("Registration of zeppelin note failed: " + res.getBody());
|
|
|
|
|
} else {
|
|
|
|
|
return res.getBody().getBody();
|
|
|
|
|
return res.getBody();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void reassignRights(final String noteId, final String jsessionid) {
|
|
|
|
|
final String url = zeppelinBaseUrl + "/api/notebook/" + noteId + "/permissions;JSESSIONID=" + jsessionid;
|
|
|
|
|
log.info("Performing PUT: " + url);
|
|
|
|
|
|
|
|
|
|
final Map<String, List<String>> rights = new LinkedHashMap<>();
|
|
|
|
|
rights.put("owners", Arrays.asList(zeppelinLogin));
|
|
|
|
|
rights.put("readers", new ArrayList<>()); // ALL
|
|
|
|
|
rights.put("runners", new ArrayList<>()); // ALL
|
|
|
|
|
rights.put("writers", new ArrayList<>()); // ALL
|
|
|
|
|
|
|
|
|
|
new RestTemplate().put(url, rights);
|
|
|
|
|
private <T extends HasStatus> T findNewJsessionId(final HttpMethod method, final String api, final Class<T> resClazz, final Object objRequest) {
|
|
|
|
|
for (final String id : obtainJsessionIDs()) {
|
|
|
|
|
try {
|
|
|
|
|
final T res = callApi(method, api, resClazz, objRequest, id);
|
|
|
|
|
setJsessionid(id);
|
|
|
|
|
return res;
|
|
|
|
|
} catch (final MDStoreManagerException e) {
|
|
|
|
|
log.warn("Skipping invalid jsessionid: " + id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void deleteNote(final String id, final String jsessionid) {
|
|
|
|
|
final String url = zeppelinBaseUrl + "/api/notebook/" + id + ";JSESSIONID=" + jsessionid;
|
|
|
|
|
log.debug("Performing DELETE: " + url);
|
|
|
|
|
new RestTemplate().delete(url);
|
|
|
|
|
}
|
|
|
|
|
private Set<String> obtainJsessionIDs() {
|
|
|
|
|
|
|
|
|
|
private boolean isExpired(final String id, final String jsessionid) {
|
|
|
|
|
// TODO Auto-generated method stub
|
|
|
|
|
return false;
|
|
|
|
|
final HttpHeaders headers = new HttpHeaders();
|
|
|
|
|
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
|
|
|
|
|
|
|
|
|
final MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
|
|
|
|
map.add("userName", zeppelinLogin);
|
|
|
|
|
map.add("password", zeppelinPassword);
|
|
|
|
|
final HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
|
|
|
|
|
|
|
|
|
|
final String url = zeppelinBaseUrl + "/api/login";
|
|
|
|
|
final ResponseEntity<?> res = new RestTemplate().postForEntity(url, request, Object.class);
|
|
|
|
|
|
|
|
|
|
if (res.getStatusCode() != HttpStatus.OK) {
|
|
|
|
|
log.error("Zeppelin API: login failed with HTTP error: " + res);
|
|
|
|
|
throw new RuntimeException("Zeppelin API: login failed with HTTP error: " + res);
|
|
|
|
|
} else if (!res.getHeaders().containsKey(HttpHeaders.SET_COOKIE)) {
|
|
|
|
|
log.error("Zeppelin API: login failed (missing SET_COOKIE header)");
|
|
|
|
|
throw new RuntimeException("Zeppelin API: login failed (missing SET_COOKIE header)");
|
|
|
|
|
} else {
|
|
|
|
|
return res.getHeaders()
|
|
|
|
|
.get(HttpHeaders.SET_COOKIE)
|
|
|
|
|
.stream()
|
|
|
|
|
.map(s -> s.split(";"))
|
|
|
|
|
.flatMap(Arrays::stream)
|
|
|
|
|
.map(String::trim)
|
|
|
|
|
.filter(s -> s.startsWith("JSESSIONID="))
|
|
|
|
|
.map(s -> StringUtils.removeStart(s, "JSESSIONID="))
|
|
|
|
|
.filter(s -> !s.equalsIgnoreCase("deleteMe"))
|
|
|
|
|
.collect(Collectors.toSet());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getJsessionid() {
|
|
|
|
|