Skip to content

Commit

Permalink
update metadata config from text to drop down + text
Browse files Browse the repository at this point in the history
  • Loading branch information
Ted Xiao committed Nov 28, 2016
1 parent c0a3888 commit b6c8513
Show file tree
Hide file tree
Showing 9 changed files with 383 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
package com.splunk.splunkjenkins;

import com.splunk.splunkjenkins.model.EventType;
import com.splunk.splunkjenkins.model.MetaDataConfigItem;
import hudson.Extension;
import hudson.util.FormApply;
import hudson.util.FormValidation;
import jenkins.model.GlobalConfiguration;
import jenkins.model.Jenkins;
import jenkins.model.JenkinsLocationConfiguration;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;

import javax.servlet.ServletException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.net.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import static com.splunk.splunkjenkins.Constants.*;
import static com.splunk.splunkjenkins.utils.LogEventHelper.*;
import static hudson.Util.getHostName;
import static java.util.regex.Pattern.CASE_INSENSITIVE;
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
Expand Down Expand Up @@ -62,13 +62,16 @@ public class SplunkJenkinsInstallation extends GlobalConfiguration {
private String scriptContent;
//the app-jenkins link
private String splunkAppUrl;
private String metadataHost;
//below are all transient properties
public transient Properties metaDataProperties = new Properties();
//cached values, will not be saved to disk!
private transient String jsonUrl;
private transient String rawUrl;
private transient File scriptFile;
private transient long scriptTimestamp;
private transient String postActionScript;
private transient Set<MetaDataConfigItem> metadataItemSet = new HashSet<>();

public SplunkJenkinsInstallation(boolean useConfigFile) {
if (useConfigFile) {
Expand All @@ -79,6 +82,7 @@ public SplunkJenkinsInstallation(boolean useConfigFile) {
} catch (IOException e) {
//ignore
}
this.metadataItemSet = MetaDataConfigItem.loadProps(this.metaDataConfig);
this.updateCache();
}
}
Expand All @@ -104,6 +108,7 @@ public static boolean isLoadCompleted() {

/**
* mark this plugin as initiated
*
* @param completed mark the init as initiate completed
*/
public static void markComplete(boolean completed) {
Expand All @@ -122,6 +127,7 @@ public static void initOnSlave(SplunkJenkinsInstallation config) {

@Override
public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
this.metadataItemSet = null; // otherwise bindJSON will never clear it once set
req.bindJSON(this, formData);
//handle choice
if ("file".equals(formData.get("commandsOrFileInSplunkins"))) {
Expand Down Expand Up @@ -424,18 +430,45 @@ public void setSplunkAppUrl(String splunkAppUrl) {
this.splunkAppUrl = splunkAppUrl;
}

public String getMetadataHost() {
if (metaDataProperties != null && metaDataProperties.containsKey("host")) {
return (String) metaDataProperties.get("host");
}
return getHostName();
}

public String getLocalHostName() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
return "yourhostname";
return "jenkins";
}
}

public Set<MetaDataConfigItem> getMetadataItemSet() {
return metadataItemSet;
}

public String getMetadataHost() {
if (metadataHost != null) {
return metadataHost;
} else {
//backwards compatible
if (metaDataProperties != null && metaDataProperties.containsKey("host")) {
return metaDataProperties.getProperty("host");
} else {
String url = JenkinsLocationConfiguration.get().getUrl();
if (url != null && !url.startsWith("http://localhost")) {
try {
return (new URL(url)).getHost();
} catch (MalformedURLException e) {
//do not care,just ignore
}
}
return getLocalHostName();
}
}
}

public void setMetadataHost(String metadataHost) {
this.metadataHost = metadataHost;
}

public void setMetadataItemSet(Set<MetaDataConfigItem> metadataItemSet) {
this.metadataItemSet = metadataItemSet;
this.metaDataConfig = MetaDataConfigItem.toString(metadataItemSet);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import static com.splunk.splunkjenkins.model.EventType.CONSOLE_LOG;

public class EventRecord {
private final static String METADATA_KEYS[] = {"index", "source", "host", EVENT_SOURCE_TYPE};
private final static String METADATA_KEYS[] = {"index", "source", EVENT_SOURCE_TYPE};
private long time;
private int retryCount;
private Object message;
Expand Down Expand Up @@ -117,6 +117,7 @@ private Map<String, String> getMetaData(SplunkJenkinsInstallation config) {
.putIfAbsent(metaDataKey, config.getMetaData(eventType.getKey(metaDataKey)))
.putIfAbsent(metaDataKey, config.getMetaData(metaDataKey));
}
metaDataBuilder.putIfAbsent("host", config.getMetadataHost());
return metaDataBuilder.getQueryMap();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package com.splunk.splunkjenkins.model;

import com.google.common.collect.ImmutableMap;
import hudson.Extension;
import hudson.model.Describable;
import hudson.model.Descriptor;
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;
import org.kohsuke.stapler.DataBoundConstructor;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
* @since 1.4
* Helper class for metdata configure
*/
public class MetaDataConfigItem implements Describable<MetaDataConfigItem> {
private static final String DISABLED_KEY = "disabled";
private static final Map<String, String> CONFIG_ITEM_MAP = new ImmutableMap.Builder<String, String>().put("Index", "index")
.put("Source Type", "sourcetype").put("Disabled", DISABLED_KEY).build();
@Nonnull
private String dataSource;
@Nonnull
private String keyName;
//can only be null if enabled is false
private String value;

@Nonnull
public String getDataSource() {
return dataSource;
}

public void setDataSource(@Nonnull String dataSource) {
this.dataSource = dataSource;
}

@Nonnull
public String getKeyName() {
return keyName;
}

public void setKeyName(@Nonnull String keyName) {
this.keyName = keyName;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

@DataBoundConstructor
public MetaDataConfigItem(String dataSource, String keyName, String value) {
this.dataSource = dataSource;
this.keyName = keyName;
this.value = value;
}

@Override
public int hashCode() {
return toString().hashCode();
}

@Override
public String toString() {
if (!DISABLED_KEY.equals(this.keyName)) {
return "" + this.dataSource + "|" + this.keyName + "|" + this.value;
} else {
return "" + this.dataSource + "|" + this.keyName;
}
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof MetaDataConfigItem) || obj == null) {
return false;
}
return this.toString().equals(obj.toString());
}

@Override
public Descriptor<MetaDataConfigItem> getDescriptor() {
return Jenkins.getInstance().getDescriptor(getClass());
}

@Extension
public static class DescriptorImpl extends Descriptor<MetaDataConfigItem> {

@Override
public String getDisplayName() {
return "Metadata config";
}

/**
* This method determines the values of the album drop-down list box.
*/
public ListBoxModel doFillDataSourceItems() {
ListBoxModel m = new ListBoxModel();
m.add("Build Event", EventType.BUILD_EVENT.toString());
m.add("Build Report", EventType.BUILD_REPORT.toString());
m.add("Console Log", EventType.CONSOLE_LOG.toString());
m.add("Jenkins Config", EventType.JENKINS_CONFIG.toString());
m.add("Log File", EventType.FILE.toString());
m.add("Queue Information", EventType.QUEUE_INFO.toString());
m.add("Slave Information", EventType.SLAVE_INFO.toString());
return m;
}

/**
* This method determines the values of the album drop-down list box.
*/
public static ListBoxModel doFillKeyNameItems() {
ListBoxModel m = new ListBoxModel();
for (Map.Entry<String, String> entry : CONFIG_ITEM_MAP.entrySet()) {
m.add(entry.getKey(), entry.getValue());
}
return m;
}
}

public static Set<MetaDataConfigItem> loadProps(String properties) {
Set<MetaDataConfigItem> config = new HashSet<>();
if (properties != null) {
Properties metaDataConfigProps = new Properties();
try {
metaDataConfigProps.load(new StringReader(properties));
for (EventType eventType : EventType.values()) {
//backward compatible, xx.enabled=false
if ("false".equals(metaDataConfigProps.getProperty(eventType.getKey("enabled")))) {
config.add(new MetaDataConfigItem(eventType.toString(), DISABLED_KEY, ""));
} else {
for (String suffix : CONFIG_ITEM_MAP.values()) {
String lookupKey = eventType.getKey(suffix);
if (metaDataConfigProps.containsKey(lookupKey)) {
config.add(new MetaDataConfigItem(eventType.toString(), suffix,
metaDataConfigProps.getProperty(lookupKey)));
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
return config;
}

/**
* Convert config set to plain text string, just to keep backward compatibility
*
* @param configs
* @return string
*/
public static String toString(Set<MetaDataConfigItem> configs) {
StringBuffer sbf = new StringBuffer();
if (configs == null || configs.isEmpty()) {
return "";
}
Set<String> disabledKeys = new HashSet<>();
for (EventType eventType : EventType.values()) {
MetaDataConfigItem disabledItem = new MetaDataConfigItem(eventType.toString(), DISABLED_KEY, "");
if (configs.contains(disabledItem)) {
disabledKeys.add(eventType.toString());
}
}
for (String keyName : disabledKeys) {
sbf.append(keyName.toLowerCase()).append(".").append("enabled=false\n");
}
for (MetaDataConfigItem config : configs) {
if (disabledKeys.contains(config.dataSource)) {
continue;
}
sbf.append(config.dataSource.toLowerCase()).append(".").append(config.keyName).append("=")
.append(config.value).append("\n");

}
return sbf.toString();
}

public String getCssDisplay() {
if (DISABLED_KEY.equals(this.keyName)) {
return "display:none";
} else {
return "display:''";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@
help="/descriptorByName/com.splunk.splunkjenkins.SplunkJenkinsInstallation/help/httpInputConfig">
<f:checkbox default="true"/>
</f:entry>
<f:entry title="${%Raw Events Supported}" field="rawEventEnabled">
<f:checkbox default="true"/>
</f:entry>
<f:entry title="${%MetaData}" field="metaDataConfig">
<f:textarea default="${%default_metadata(instance.getLocalHostName())}"/>
<f:entry title="${%Jenkins Master Hostname}" field="metadataHost">
<f:textbox clazz="required"/>
</f:entry>

<f:validateButton title="${%Test Connection}" progress="${%Testing...}" method="testHttpInput"
with="host,port,token,useSSL,metaDataConfig"/>
<f:advanced>
<f:entry title="${%Raw Events Supported}" field="rawEventEnabled">
<f:checkbox default="true"/>
</f:entry>
<f:entry title="${%Custom Data Source}">
<f:repeatable field="metadataItemSet">
<st:include page="config.jelly" class="${descriptor.clazz}"/>
</f:repeatable>
</f:entry>
<f:entry title="${%Splunk App for Jenkins Link}" field="splunkAppUrl">
<f:textbox/>
</f:entry>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div>
Jenkins master hostname, used in Splunk query
<code>
search host="servername"
</code>
</div>
Loading

0 comments on commit b6c8513

Please sign in to comment.