Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
158 changes: 158 additions & 0 deletions src/main/java/com/cloudbees/syslog/SDElement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* Copyright 2010-2014, CloudBees Inc.
*
* Licensed 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 com.cloudbees.syslog;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
* A SD-ELEMENT
*
* @author <a href="mailto:brett@thebergquistfamily.com">Brett Bergquist</a>
*/
public class SDElement implements Serializable {

private static final long serialVersionUID = 1L;

/**
* Reserved SD-IDs as documented in <a href="https://www.rfc-editor.org/rfc/rfc5424.txt">RFC-5424</a>
*/
public static final String[] RESERVED_SDID = new String[]{
"timeQuality",
"tzKnown",
"isSynced",
"syncAccuracy"
};

public SDElement(String sdID) {
validateSDID(sdID);
this.sdID = sdID;
}

public SDElement(String sdID, SDParam... sdParams) {
validateSDID(sdID);
this.sdID = sdID;
this.sdParams.addAll(Arrays.asList(sdParams));
}

private String sdID;

/**
* Get the value of sdID
*
* @return the value of sdID
*/
public String getSdID() {
return sdID;
}

private List<SDParam> sdParams = new ArrayList<SDParam>();

/**
* Get the value of sdParams
*
* @return the value of sdParams
*/
public List<SDParam> getSdParams() {
return sdParams;
}

/**
* Set the value of sdParams
*
* @param sdParams new value of sdParams
*/
public void setSdParams(List<SDParam> sdParams) {
if (null == sdParams) {
throw new IllegalArgumentException("sdParams list cannot be null");
}
this.sdParams.addAll(sdParams);
}

/**
* Adds a SDParam
* @param paramName the PARAM-NAME
* @param paramValue the PARAM-VALUE
* @return
*/
public SDElement addSDParam(String paramName, String paramValue) {
return addSDParam(new SDParam(paramName, paramValue));
}

public SDElement addSDParam(SDParam sdParam) {
this.sdParams.add(sdParam);
return this;
}

@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + Objects.hashCode(this.sdID);
return hash;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final SDElement other = (SDElement) obj;
return Objects.equals(this.sdID, other.sdID);
}

private void validateSDID(String sdName) {
if (null == sdName) {
throw new IllegalArgumentException("SD-ID cannot be null");
}
if (sdName.length() > 32) {
throw new IllegalArgumentException("SD-ID must be less than 32 characters: " + sdName);
}
if (sdName.contains("=")) {
throw new IllegalArgumentException("SD-ID cannot contain '='");
}
if (sdName.contains(" ")) {
throw new IllegalArgumentException("SD-ID cannot contain ' '");
}
if (sdName.contains("]")) {
throw new IllegalArgumentException("SD-ID cannot contain ']'");
}
if (sdName.contains("\"")) {
throw new IllegalArgumentException("SD-ID cannot contain '\"'");
}
if (! sdName.contains("@")) {
boolean found = false;
for (String rn : RESERVED_SDID) {
if (rn.equals(sdName)) {
found = true;
break;
}
}
if (! found) {
throw new IllegalArgumentException("SD-ID is not known registered SDID: " + sdName);
}
}
}

}
131 changes: 131 additions & 0 deletions src/main/java/com/cloudbees/syslog/SDParam.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* Copyright 2010-2014, CloudBees Inc.
*
* Licensed 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 com.cloudbees.syslog;

import java.io.Serializable;
import java.util.Objects;

/**
*
* @author <a href="mailto:brett@thebergquistfamily.com">Brett Bergquist</a>
*/
public class SDParam implements Serializable {

private static final long serialVersionUID = 1L;

public SDParam(String paramName, String paramValue) {
validateParamName(paramName);
this.paramName = paramName;
this.paramValue = paramValue;
}

private String paramName;

/**
* Get the value of paramName
*
* @return the value of paramName
*/
public String getParamName() {
return paramName;
}

/**
* Set the value of paramName
*
* @param paramName new value of paramName
*/
public void setParamName(String paramName) {
validateParamName(paramName);
this.paramName = paramName;
}

private String paramValue;

/**
* Get the value of paramValue
*
* @return the value of paramValue
*/
public String getParamValue() {
return paramValue;
}

/**
* Set the value of paramValue
*
* @param paramValue new value of paramValue
*/
public void setParamValue(String paramValue) {
this.paramValue = paramValue;
}

private void validateParamName(String sdName) {
if (null == sdName) {
throw new IllegalArgumentException("PARAM-NAME cannot be null");
}
if (sdName.length() > 32) {
throw new IllegalArgumentException("PARAM-NAME must be less than 32 characters: " + sdName);
}
if (sdName.contains("=")) {
throw new IllegalArgumentException("PARAM-NAME cannot contain '='");
}
if (sdName.contains(" ")) {
throw new IllegalArgumentException("PARAM-NAME cannot contain ' '");
}
if (sdName.contains("]")) {
throw new IllegalArgumentException("PARAM-NAME cannot contain ']'");
}
if (sdName.contains("\"")) {
throw new IllegalArgumentException("PARAM-NAME cannot contain '\"'");
}
}

@Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + Objects.hashCode(this.paramName);
hash = 59 * hash + Objects.hashCode(this.paramValue);
return hash;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final SDParam other = (SDParam) obj;
if (!Objects.equals(this.paramName, other.paramName)) {
return false;
}
if (!Objects.equals(this.paramValue, other.paramValue)) {
return false;
}
return true;
}

@Override
public String toString() {
return "SDParam{" + "paramName=" + paramName + ", paramValue=" + paramValue + '}';
}

}
74 changes: 73 additions & 1 deletion src/main/java/com/cloudbees/syslog/SyslogMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

Expand Down Expand Up @@ -91,6 +93,7 @@ protected String newObject() {
private String appName;
private String procId;
private String msgId;
private Set<SDElement> sdElements;
/**
* Use a {@link java.io.CharArrayWriter} instead of a {@link String} or a {@code char[]} because middlewares like
* Apache Tomcat use {@code CharArrayWriter} and it's convenient for pooling objects.
Expand Down Expand Up @@ -213,6 +216,26 @@ public SyslogMessage withMsg(final String msg) {
}
});
}

public Set<SDElement> getSDElements() {
Set<SDElement> ssde = sdElements;
if (ssde == null) {
ssde = new HashSet<SDElement>(0);
}
return ssde;
}

public void setSDElements(Set<SDElement> ssde) {
this.sdElements = ssde;
}

public SyslogMessage withSDElement(SDElement sde) {
if (sdElements == null) {
sdElements = new HashSet<SDElement>();
}
sdElements.add(sde);
return this;
}

/**
* Generates a Syslog message complying to the <a href="http://tools.ietf.org/html/rfc5424">RFC-5424</a> format
Expand Down Expand Up @@ -287,7 +310,7 @@ public void toRfc5424SyslogMessage(Writer out) throws IOException {
out.write(SP);
writeNillableValue(msgId, out);// Message ID
out.write(SP);
out.write(NILVALUE); // structured data
writeStructuredDataOrNillableValue(sdElements, out);
if (msg != null) {
out.write(SP);
msg.writeTo(out);
Expand Down Expand Up @@ -339,4 +362,53 @@ protected void writeNillableValue(@Nullable String value, @Nonnull Writer out) t
out.write(value);
}
}

protected void writeStructuredDataOrNillableValue(@Nullable Set<SDElement> ssde, @Nonnull Writer out) throws IOException {
if (ssde == null || ssde.isEmpty()) {
out.write(NILVALUE);
} else {
for (SDElement sde : ssde) {
writeSDElement(sde, out);
}
}
}

protected void writeSDElement(@Nonnull SDElement sde, @Nonnull Writer out) throws IOException {
out.write("[");
out.write(sde.getSdID());
for (SDParam sdp : sde.getSdParams()) {
writeSDParam(sdp, out);
}
out.write("]");
}

protected void writeSDParam(@Nonnull SDParam sdp, @Nonnull Writer out) throws IOException {
out.write(SP);
out.write(sdp.getParamName());
out.write('=');
out.write('"');
out.write(getEscapedParamValue(sdp.getParamValue()));
out.write('"');
}

protected String getEscapedParamValue(String paramValue) {
StringBuilder sb = new StringBuilder(paramValue.length());

for (int i = 0; i < paramValue.length(); i++) {
char c = paramValue.charAt(i);
switch (c) {
// Falls through
case '"':
case '\\':
case ']':
sb.append('\\');
break;
default:
break;
}
sb.append(c);
}

return sb.toString();
}
}
Loading