/*******************************************************************************
* Copyright (c) 2015 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package com.openshift.internal.restclient.capability.resources;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.openshift.restclient.IClient;
import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption;
import com.openshift.restclient.capability.resources.IPodLogRetrieval;
import com.openshift.restclient.model.IPod;
public class OpenShiftBinaryPodLogRetrieval implements IPodLogRetrieval {
private static final Logger LOG = LoggerFactory.getLogger(IPodLogRetrieval.class);
private IPod pod;
private IClient client;
private Map<String, PodLogs> cache = new HashMap<>();
public OpenShiftBinaryPodLogRetrieval(IPod pod, IClient client) {
this.pod = pod;
this.client = client;
}
@Override
public boolean isSupported() {
return true;
}
@Override
public String getName() {
return OpenShiftBinaryPodLogRetrieval.class.getSimpleName();
}
@Override
public InputStream getLogs(final boolean follow, final OpenShiftBinaryOption... options) {
return getLogs(follow, null, options);
}
@Override
public InputStream getLogs(final boolean follow, final String container, final OpenShiftBinaryOption... options) {
final String normalizedContainer = StringUtils.defaultIfBlank(container, "");
synchronized (cache) {
if(cache.containsKey(normalizedContainer)) {
return cache.get(normalizedContainer).getLogs();
}
PodLogs logs = null;
try {
logs = new PodLogs(client, follow, normalizedContainer, options);
return logs.getLogs();
}catch(Exception e) {
throw e;
}finally {
if(logs != null) {
cache.put(normalizedContainer, logs);
}
}
}
}
@Override
public void stop() {
new ArrayList<>(cache.keySet()).forEach(c->stop(c));
}
@Override
public synchronized void stop(String container) {
if(!cache.containsKey(container)) return;
try {
PodLogs logs = cache.remove(container);
logs.stop();
}catch(Exception e) {
LOG.warn("Unable to stop pod logs",e);
}
}
private class PodLogs extends AbstractOpenShiftBinaryCapability{
private String container;
private boolean follow;
private SequenceInputStream is;
private OpenShiftBinaryOption[] options;
PodLogs(IClient client, boolean follow, String container, OpenShiftBinaryOption... options){
super(client);
this.follow = follow;
this.container = container;
this.options = options;
}
public synchronized InputStream getLogs() {
if(is == null) {
start(options);
is = new SequenceInputStream(getProcess().getInputStream(), getProcess().getErrorStream());
}
return is;
}
@Override
public boolean isSupported() {
return true;
}
@Override
public String getName() {
return "";
}
@Override
protected void cleanup() {
follow = false;
if(getProcess() != null) {
IOUtils.closeQuietly(getProcess().getInputStream());
IOUtils.closeQuietly(getProcess().getErrorStream());
}
synchronized (cache) {
cache.remove(this.container);
}
}
@Override
protected boolean validate() {
return true;
}
@Override
protected String buildArgs(final List<OpenShiftBinaryOption> options) {
final StringBuilder argsBuilder = new StringBuilder();
argsBuilder.append("logs ");
if(options.contains(OpenShiftBinaryOption.SKIP_TLS_VERIFY)) {
argsBuilder.append(getSkipTlsVerifyFlag());
}
argsBuilder.append(getServerFlag()).append(" ")
.append(pod.getName()).append(" ").append("-n ").append(pod.getNamespace()).append(" ")
.append(getTokenFlag());
if(follow) {
argsBuilder.append(" -f ");
}
if(StringUtils.isNotBlank(container)) {
argsBuilder.append( " -c ").append(container);
}
return argsBuilder.toString();
}
}
}