blob: 54329c3d0c9de4a992089cab47cf726ca630946c [file] [log] [blame]
/*
* 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.geode.management.api;
import static org.apache.commons.lang3.StringUtils.isBlank;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.geode.annotations.Experimental;
import org.apache.geode.management.configuration.Links;
/**
* This base class provides the common attributes returned from all {@link ClusterManagementService}
* methods
*/
@Experimental
public class ClusterManagementResult {
/**
* these status codes generally have a one-to-one mapping to the http status code returned by the
* REST controller
*/
public enum StatusCode {
/** operation is successful, configuration is realized and persisted */
OK,
/** configuration failed validation */
ILLEGAL_ARGUMENT,
/** user is not authenticated */
UNAUTHENTICATED,
/** user is not authorized to do this operation */
UNAUTHORIZED,
/** entity you are trying to create already exists */
ENTITY_EXISTS,
/** entity you are trying to modify/delete is not found */
ENTITY_NOT_FOUND,
/**
* operation not successful, this includes precondition is not met (either service is not
* running or no servers available, or the configuration encountered some error when trying to
* be realized on one member (configuration is not fully realized on all applicable members).
*/
ERROR,
/**
* configuration is realized on members, but encountered some error when persisting the
* configuration. the operation is still deemed unsuccessful.
*/
FAIL_TO_PERSIST,
/** async operation launched successfully */
ACCEPTED,
/** async operation has not yet completed */
IN_PROGRESS
}
// we will always have statusCode when the object is created
protected StatusCode statusCode = StatusCode.OK;
private String statusMessage;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Links links;
/**
* for internal use only
*/
public ClusterManagementResult() {}
/**
* for internal use only
*/
public ClusterManagementResult(StatusCode statusCode, String message) {
setStatus(statusCode, message);
}
/**
* for internal use only
*/
public ClusterManagementResult(ClusterManagementResult copyFrom) {
this.statusCode = copyFrom.statusCode;
this.statusMessage = copyFrom.statusMessage;
this.links = copyFrom.links;
}
/**
* for internal use only
*/
public void setStatus(StatusCode statusCode, String message) {
this.statusCode = statusCode;
this.statusMessage = formatErrorMessage(message);
}
/**
* Capitalized the first letter and adds a period, if needed.
* This helps the CMS API give a consistent format to error messages, even when they sometimes
* come from parts of the system beyond our control.
*/
private static String formatErrorMessage(String message) {
if (isBlank(message)) {
return message;
}
message = message.trim();
// capitalize the first letter
char firstChar = message.charAt(0);
char newFirstChar = Character.toUpperCase(firstChar);
if (newFirstChar != firstChar) {
message = newFirstChar + message.substring(1);
}
// add a period if the sentence is not already punctuated
if (!message.endsWith(".") && !message.endsWith("!") && !message.endsWith("?")) {
message += ".";
}
return message;
}
/**
* Returns an optional message to accompany {@link #getStatusCode()}
*/
public String getStatusMessage() {
return statusMessage;
}
/**
* for internal use only
*/
public void setLinks(Links links) {
this.links = links;
}
/**
* Returns true if {@link #getStatusCode()} has a non-error value
*/
@JsonIgnore
public boolean isSuccessful() {
return statusCode == StatusCode.OK || statusCode == StatusCode.ACCEPTED
|| statusCode == StatusCode.IN_PROGRESS;
}
/**
* Returns the {@link StatusCode} for this request, such as ERROR or OK.
*/
public StatusCode getStatusCode() {
return statusCode;
}
/**
* Returns the status code and message
*/
@Override
public String toString() {
if (isBlank(getStatusMessage())) {
return getStatusCode().toString();
} else {
return getStatusCode() + ": " + getStatusMessage();
}
}
}