Web UI Services (GWT-RPC & JSON-RPC)

FlexRAID RESTful (GWT-RPC & JSON-RPC) Services

FlexRAID is an integrated software stack, and its core functionality runs as a “lean and mean” service engine.
The core service uses TCP for command communication in order to minimize its dependency on higher level protocol libraries and allow any client written in any language to interact with it.

The current distribution of FlexRAID bundles in a Web UI, which adds a set of services that communicate with the core through TCP and then present RESTful interfaces to the HTML + Ajax layer of the Web client application.

So, although FlexRAID is delivered as a single application, it is really three applications in one (3-in-1).

FlexRAID Core [TCP] -> Web UI Services [GWT-RPC & JSON-RPC] -> Web UI Interfaces (HTML + Ajax).

For client developers wishing to interact and manage FlexRAID through a higher level protocol, below are the definitions for the RPC service interface and data components.

GWT-RPC

GWT-RPC services are available at http://<host>:<port>/gwt/rpc

For more information on GWT, visit: http://code.google.com/webtoolkit/

JSON-RPC (supported in FlexRAID 2.0 beta 11 or higher)

As GWT-RPC is very specific to the GWT toolkit, a more generic protocol that can be used to create Web and non-Web (desktop) clients in any programming language is JSON-RPC.

Clients can be written in Java, C, C++, C# (.Net), Perl, PHP, Ruby, etc.

For a full list of supported language visit: http://json-rpc.org/wiki/implementations

JSON-RPC services are available at http://<host>:<port>/json/rpc

Java example of using a JSON-RPC client (Using jj1 – http://kerbtier.ch/jj1):

ServiceProxy proxy = new ServiceProxy("http://localhost:8080/json/rpc", "service");
Object result = proxy.call("getEngines");
System.out.println(result);

Output:

[{minTolerance=1, description=Generic RAID engine capable of tolerating 1 failure, name=T1 [RAID4], maxUnits=-1,
 tolerance=1, shortName=T1}, {minTolerance=1, description=Enhanced RAID engine capable of tolerating 1 failure, 
name=T1+ [RAID4], maxUnits=-1, tolerance=1, shortName=T1+}, {minTolerance=1, description=Generic RAID engine capable of 
tolerating 1 or 2 failures, name=T2 [RAID6/RAID4], maxUnits=-1, tolerance=2, shortName=T2}, {minTolerance=2, 
description=Enhanced RAID engine capable of tolerating 2 failures, name=T2+ [RAID6], maxUnits=31, tolerance=2, shortName=T2+},
 {minTolerance=1, description=Enhanced RAID engine capable of tolerating X failures where X is the number of parity units 
configured, name=Tx [RAID&#8734;], maxUnits=2147483647, tolerance=2147483647, shortName=Tx}]

JavaScript (JQuery) example of using a JSON-RPC client:
Note: this html page was created and placed under the FlexRAID <INSTALL DIR>\web folder
I named it json-rpc.html and accessed it through http://localhost:8080/json-rpc.html.
If you need cross-domain access, you will need to look into easyXDM (http://easyxdm.net/wp/).


<!doctype html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=UTF-8">

		<title>FlexRAID JSON-RPC Web Client</title>

		<script type="text/javascript" language="javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
		<script type="text/javascript" language="javascript">
			var requestId = 0;
			var getEngines = function(){
				$.ajax({
					type: "POST",
					url: "/json/rpc",
					contentType: "application/json; charset=utf-8",
					dataType: "json",
					data: JSON.stringify({method:"service.getEngines", params: [], id:requestId++}),
					success: function(responseData) {
						alert(JSON.stringify(responseData));
					},
					error: function (xhr, textStatus, errorThrown) {
						alert(xhr.responseText);
					}
				});
			};
		</script>
	</head>

	<body>
		<div>
			<form action="#">
				<input type="button" value="test" onclick="getEngines();">
			</form>
		</div>
	</body>
</html>

Clicking the test button in the above html client produces this response:

 
 
 

RPC Service Interface

public interface RPCService {
public ActionStatus<Long> getFlags();
	
	public GlobalInfoModel getGlobalInfoModel();
	
	public ActionStatus<Boolean> backupDB();
	
	public List<RAIDEngineInfoModel> getEngines();
	
	public EmailConfigModel getEmailConfig();
	public GVSMSConfigModel getGVSMSConfig();
	public ActionStatus<Boolean> save(GlobalInfoModel o);
	public ActionStatus<Boolean> save(EmailConfigModel o);
	public ActionStatus<Boolean> save(GVSMSConfigModel o);
	public ActionStatus<Boolean> test(EmailConfigModel o);
	public ActionStatus<Boolean> test(GVSMSConfigModel o);
	
	public ExternalNetworkSharesModel getExternalNetworkSharesModel();
	public ActionStatus<Boolean> save(ExternalNetworkSharesModel o);
	public ActionStatus<Boolean> canReadExternalNetworkShare(String o);
	
	public List<ScriptModel> getAllExpressionScripts();
	public ActionStatus<ScriptModel> save(ScriptModel o);
	public ActionStatus<ScriptModel> remove(ScriptModel o);
	
	public List<RAIDConfigModel> getAllRAIDConfigurations();
	public ActionStatus<RAIDConfigModel> create(AddNewConfigurationModel o);
	public ActionStatus<RAIDConfigModel> save(RAIDConfigModel o, SAVE_RAID_CONFIG_TYPE type);
	public ActionStatus<RAIDConfigModel> remove(RAIDConfigModel o);
	public ActionStatus<RAIDConfigModel> get(Long configId);
	public List<FileModel> getFilesPreview(FileModel parent);
	public List<FileModel> getFiles(FileModel parent);
	public List<FileModel> getAllAccessibleRoots();
	
	public ActionStatus<ProgressStatus> executeSnapshotAction(Long configId, String action, String[] extraProperties);
	public ActionStatus<ProgressStatus> executeRealTimeAction(Long configId, String action, String[] extraProperties);
	public ActionStatus<ProgressStatus> executeCommand(String[] args);
	public ActionStatus<Boolean> executeCommandSync(String[] args);
	public ActionStatus<ProgressStatus> status(String processId, int offset);
	
	public ActionStatus<ProgressStatus> initStoragePool(RAIDConfigModel o);
	public ActionStatus<ProgressStatus> previewStoragePool(RAIDConfigModel o);
	public ActionStatus<ProgressStatus> viewCommand(String INSTANCE_ID, String action);
       
	public PoolState getPoolState(String INSTANCE_ID);
	
	public ActionStatus<Date> addSchedule(ScheduleEntryModel entry);
	public ActionStatus<Boolean> manageTrigger(List<ScheduleInfoModel> models, TRIGGER_MANAGEMENT_ACTION action);
	public ActionStatus<Boolean> manageTrigger(String name, String group, TRIGGER_MANAGEMENT_ACTION action);
	public List<ScheduleInfoModel> getScheduleInfos();
	
	public List<StoragePoolDriveInfoModel> getStoragePoolDriveInfos(RAIDConfigModel o);
	public ActionStatus<List<String>> manageStorage(String INSTANCE_ID, String mountPoint);
	public ActionStatus<List<String>> unManageStorage(String INSTANCE_ID, String GUID, String newMountPoint);
	public ActionStatus<String> rename(String from, String to, RAIDConfigModel o);
	public ActionStatus<ProgressStatus> copyData(String from, String to, boolean syncCreateDate, boolean syncDirDate);
	public ActionStatus<ProgressStatus> copyLiveDBs(String from, String to);
	public ActionStatus<Boolean> cleanPPUs(RAIDConfigModel model);
	
	public ActionStatus<Boolean> hasParityData(String path);	
	public ActionStatus<ProgressStatus> noOpCreateAction(Long configId);
	
	public List<LiveParityBackupInfoModel> getLiveParityBackupInfo(String path);
	
	public List<FileModel> getAllDrivesForSmart();
	
	public String generateFreeSpaceChart(String chartId, int width, int height, double total, double free);
	public String generateTemperatureChart(String chartId, int width, int height, int min, int max, int value);
	public ActionStatus<String> generateTemperatureHistoryChart(String path, String type, int maxTick, int width, int height);
	
	public ActionStatus<SmartDriveInfoModel> getSmartDriveInfo(String path, String type);
	public ActionStatus<List<SmartAttributesInfoModel>> getSmartDriveAttributesInfo(String path, String type, boolean skipIfStandby);
	public ActionStatus<DriveOverviewModel> getDriveOverview(String path, String type);
	public ActionStatus<String> smartCommand(String path, String command, String type);
	public ActionStatus<Boolean> save(SmartMonitoringModel o);
	public ActionStatus<Boolean> saveSmartMonitoringOptions(String mountPoint, boolean active, boolean skipWhenInStandby, int updateInterval, String updateType);
	public ActionStatus<Boolean> saveSmartMonitoringMappings(String pathMappings, String typeMappings);
	public ActionStatus<String> generateAttributeChart(final String attributeName, final String chartId, int maxTick, final int width, final int height, List<LabelValueModel<Long, Integer>> entries);
}

 
 

Note on INSTANCE_ID as used in “public PoolState getPoolState(String INSTANCE_ID);” and others:
INSTANCE_ID = STORAGE_POOL_TYPE + StoragePoolInfoModel.instanceId
For the Web UI, INSTANCE_ID is implemented in StoragePoolInfoModel as a run time value:
public String getViewInstanceID() {
return storagePoolType.getClass_prefix() + instanceId;
}

Where STORAGE_POOL_TYPE is implemented as:

public enum STORAGE_POOL_TYPE {
	WINDOWS_CLASS1("class1_"), WINDOWS_CLASS2("class2_"), LINUX_FUSE("class1_");
	
	private final String class_prefix;
	
	STORAGE_POOL_TYPE(String class_prefix){
		this.class_prefix = class_prefix;
	}

	public String getClass_prefix() {
		return class_prefix;
	}
}

 
 
 

public class GlobalInfoModel implements Serializable {
        private static final long serialVersionUID = -4474898802640771549L;

	public static enum OSTYPE {WINDOWS, LINUX};

	private OSTYPE osType;
	private String lastLoadedVersion;
	private boolean reload;
	private String lastLocale;
	private boolean useOldDriver;
	private String sudoPassword;
	private List<LabelValueModel<String, String>> managedGUIDs;
	private String devicePathMappings;
	private String deviceTypeMappings;
}
public class ActionStatus<T> implements Serializable {
 private static final long serialVersionUID = 8038069917336185060L;
 private boolean success;
 private String message;
 private T payload;
}
public class RAIDEngineInfoModel implements Serializable {
 private static final long serialVersionUID = 6595951319673739207L;

 private String shortName;
 private String name;
 private String description;
 private Long tolerance;
 private Short minTolerance;
 private Long maxUnits;
}

public class EmailConfigModel implements Serializable, NotificationOptions {
 private static final long serialVersionUID = 2860120496066205934L;

 private boolean active;
 private String host;
 private int port;
 private String userName;
 private String password;
 private String sender;
 private String recipient;
 private String cc;
 private String bcc;
 private boolean ssl;

 private boolean createSuccess;
 private boolean createFailed;
 private boolean createScheduleOnly;

 private boolean updateSuccess;
 private boolean updateFailed;
 private boolean updateScheduleOnly;

 private boolean validateSuccess;
 private boolean validateFailed;
 private boolean validateScheduleOnly;

 private boolean verifySuccess;
 private boolean verifyFailed;
 private boolean verifyScheduleOnly;

 private boolean restoreSuccess;
 private boolean restoreFailed;
 private boolean restoreScheduleOnly;

 private boolean onSmart;
}
public class GVSMSConfigModel implements Serializable, NotificationOptions {
 private static final long serialVersionUID = -7932882066827217098L;

 private boolean active;
 private String userName;
 private String password;
 private String recipient;

 private boolean createSuccess;
 private boolean createFailed;
 private boolean createScheduleOnly;

 private boolean updateSuccess;
 private boolean updateFailed;
 private boolean updateScheduleOnly;

 private boolean validateSuccess;
 private boolean validateFailed;
 private boolean validateScheduleOnly;

 private boolean verifySuccess;
 private boolean verifyFailed;
 private boolean verifyScheduleOnly;

 private boolean restoreSuccess;
 private boolean restoreFailed;
 private boolean restoreScheduleOnly;

 private boolean onSmart;
}
public class ExternalNetworkSharesModel implements Serializable {
 private static final long serialVersionUID = 7757906911216210266L;

 private String shares;
}
public class ScriptModel implements Serializable {
 private static final long serialVersionUID = 3133814641237841252L;

 private long id;
 private String name;
 private String script;
}
public class RAIDConfigModel implements Serializable {
 private static final long serialVersionUID = -7776193400619316679L;

 public static enum SAVE_RAID_CONFIG_TYPE {
 DRU, PPU, URU, TASK_PROPS, VIEW_CONFIG
 };

 private long id;
 private CONFIGURATION_MODE mode;
 private CONFIGURATION_TYPE type;
 private StoragePoolInfoModel storagePoolInfo;
 private String name;
 private RAIDEngineInfoModel engine;
 private String description;
 private List<FileContainerModel> drus;
 private List<FileContainerModel> ppus;
 private FileContainerModel uru;
 private List<RunTimePropertyModel> runtimeProperties;
 private boolean initialized;
 private boolean failedCreate;
 private boolean running;
 private String runId;
 private String runAction;
}

public class StoragePoolInfoModel implements Serializable {
        private static final long serialVersionUID = -5036068102623734269L;

	private int instanceId;
	private String mountPoint;
	private String viewConfig;
	private String backupPath;

	private STORAGE_POOL_MERGE_MODE storagePoolMergeMode;
	private STORAGE_POOL_TYPE storagePoolType;

	private int autoStartDelay;
	private List<StoragePoolShareModel> shares = new ArrayList<StoragePoolShareModel>();
}
public enum STORAGE_POOL_MERGE_MODE {
 AUTO_FOLDER, AUTO_SPACE, EXPLICIT
}
public enum STORAGE_POOL_TYPE {
 WINDOWS_CLASS1, WINDOWS_CLASS2, LINUX_FUSE
}
public class StoragePoolShareModel implements Serializable {
        private static final long serialVersionUID = -7275852114531597049L;

	public static enum SHARE_PERMISSION {READ, CHANGE, FULL};

	private String path;
	private String shareName;
	private String userName;
	private SHARE_PERMISSION sharePermission;
}
public class FileContainerModel implements Serializable {
 private static final long serialVersionUID = -6963202773149690057L;

 private boolean locked;
 private List<FileModel> files = new ArrayList<FileModel>();
}
public class FileModel implements Serializable {
        private static final long serialVersionUID = 8851297013227112589L;

	private String id;
	private String name;
	private String path;
	private String oldPath;
	private boolean file;
	private String extMapping;

	private boolean hidden;
	private boolean locked;
	private DRIVE_TYPE driveType;
}
public class RunTimePropertyModel implements Serializable {
 private static final long serialVersionUID = 3070249524207169752L;
 private String name;
 private String label;
 private String value;
 private boolean advanced;
 private boolean changeableAfterCreate;
 private String description;
 private boolean multiLine;
}
public class AddNewConfigurationModel implements Serializable {
 private static final long serialVersionUID = 4384906060580271035L;

 private String name;
 private CONFIGURATION_TYPE type;
 private CONFIGURATION_MODE mode;
 private int drus;
 private int ppus;
 private boolean uru;
 private String engine;
 private String configImport;
 private String description;
}
public enum DRIVE_TYPE {
 DRIVE_UNKNOWN, DRIVE_NO_ROOT_DIR, DRIVE_REMOVABLE, DRIVE_FIXED, DRIVE_REMOTE, DRIVE_CDROM, DRIVE_RAMDISK, DRIVE_UNC, DRIVE_ERROR
}
public class ProgressStatus implements Serializable{
 private static final long serialVersionUID = -2386454364934896476L;
 public static enum STATUS {STATUS_STARTED, STATUS_PROCESSING, STATUS_COMPLETED,
 STATUS_ABORTED, STATUS_ABORTING,
 STATUS_PAUSED, STATUS_PAUSING,
 STATUS_RESUMED, STATUS_RESUMING};

 private String actionId;
 private STATUS status;
 private List<String> messages;
 private long startTime;
 private long endTime;
 private List<ClientProgressInfo> progresses = new ArrayList<ClientProgressInfo>();
}

public class ClientProgressInfo implements Serializable {
 private static final long serialVersionUID = -4560496644424715055L;

 private String name;
 private boolean ioProgress;
 private long startTime;
 private long pausedTime;
 private long refTime;

 private long totalSize;
 private long remainingSize;

 private boolean ended;
 private List<ClientProgressInfo> subProgresses;
}
public class PoolState implements Serializable {
        private static final long serialVersionUID = 1040455182727493183L;

	private boolean installed;
	private boolean rebootRequired;
	private boolean published;
	private boolean running;
	private boolean hasAutoStart;
	private boolean hasSharesToReconnect;
	private long remainingDelay;
	private boolean starting;
	private boolean stopping;
}
public class ScheduleEntryModel implements Serializable {
 private static final long serialVersionUID = 5432048153353828369L;

 private ScheduleTypeModel schedulerType;
 private LabelValueModel action;

 protected String seconds;
 protected String minutes;
 protected String hours;
 protected String dmonths;
 protected String months;
 protected String dweeks;
 protected String years;

 protected String every;
 protected String atHour;
 protected String atMinute;
 protected String atSecond;
 protected String onDay;
 protected String onMonth;
 protected String onYear;
 protected String startingDay;
 protected String startingMonth;
 protected String startingYear;
 protected String startingHour;
 protected String startingMinute;
 protected String startingSecond;
 protected String endingDay;
 protected String endingMonth;
 protected String endingYear;
 protected String endingHour;
 protected String endingMinute;
 protected String endingSecond;

 protected String cron;
}

public class ScheduleTypeModel implements Serializable {
 private static final long serialVersionUID = -7592202515865480640L;

 public static enum SCHEDULE_TYPE {COMMAND, SNAPSHOT, REALTIME, POOL, SCRIPT};

 private Long configId;
 private String name;
 private SCHEDULE_TYPE type;
}
public enum TRIGGER_MANAGEMENT_ACTION {
 PAUSE_ALL, PAUSE_JOB_GROUP, PAUSE_JOB, PAUSE_TRIGGER_GROUP, PAUSE_TRIGGER,
 RESUME_ALL, RESUME_JOB_GROUP, RESUME_JOB, RESUME_TRIGGER_GROUP, RESUME_TRIGGER,
 CANCEL_JOB, CANCEL_TRIGGER
}

public class StoragePoolDriveInfoModel implements Serializable {
        private static final long serialVersionUID = 7447033593084705660L;

	public static enum UoR_TYPE {DRU, PPU, URU, NONE};
	public static enum HEALTH_STATUS {HEALTHY, MISSING};
	public static enum DRIVE_STATE{IN_POOL, MISSING_FROM_POOL, NOT_IN_POOL, SYSTEM_DRIVE, NETWORK_DRIVE, MEDIA, OTHER};

	private String guid;
	private String name;
	private String path;
	private String oldPath;
	private String label;
	private DRIVE_TYPE driveType;
	private UoR_TYPE uorType;
	private HEALTH_STATUS status;
	private DRIVE_STATE state;
	private long capacity;
	private long freeSpace;
	private boolean locked;
	private int uorPos;
}
public enum CONFIGURATION_MODE {
 CRUISE_CONTROL, EXPERT
}
public enum CONFIGURATION_TYPE {
 SNAPSHOT, REALTIME, STORAGE_POOL_ONLY
}
public class LabelValueModel<K,V> implements Serializable {
 private static final long serialVersionUID = -4308104336536985544L;
 private K label;
 private V value;
}
public class LiveParityBackupInfoModel implements Serializable {
        private static final long serialVersionUID = 1060766413733785714L;

	private String path;
	private Date date;
	private int coreCount;
	private int druCount;
}
public class DriveOverviewModel implements Serializable {
	private static final long serialVersionUID = 176201280623045856L;
	
	private String diskSpaceChartHtml;
	private String temperatureChartHtml;
	private SmartDriveInfoModel driveInfo;
	private List<SmartAttributesInfoModel> attributes;
	private SmartMonitoringModel monitoring;
	private String errorMessage;
}
public class SmartDriveInfoModel implements Serializable{
	private static final long serialVersionUID = -4889427080949398642L;
	
	private boolean hasSmart;
	private boolean smartEnabled;
	private List<LabelValueModel<String, String>> properties;
	private List<String> notes;
}
public class SmartAttributesInfoModel implements Serializable {
	private static final long serialVersionUID = -4793370178800725632L;
	
	private int id;
	private String name;
	private String flag;
	private String value;
	private String worst;
	private String threshold;
	private String type;
	private String updated;
	private String whenFailed;
	private String rawValue;
}
public class SmartMonitoringModel implements Serializable{
	private static final long serialVersionUID = 867530352857337936L;
	
	public enum UPDATE_TYPE {MINUTE, HOUR, DAY, WEEK, MONTH, YEAR}
	
	private String mountPoint;
	private boolean active;
	private boolean skipWhenInStandby; //Skip when drive is in sleep/standby mode (prevents spin-up)
	private int updateInterval;
	private UPDATE_TYPE updateType;
	private long startDate;
	private long lastUpdateDate;
	private Map<Integer, List<LabelValueModel<Long, Integer>>> attributes;
}
  • public ActionStatus executeSnapshotAction(Long configId, String action, String[] extraProperties);

    Where configId is RAIDConfigModel.id and action is either create, update, verify, force-sync-verify, validate, quick-validate, or fast-expansion.
    The parameter extraProperties is usually null except for:
    - restore, where an extra string is passed in the form of: restore=DRUx/PPUx{Path1;Path2;etc.}
    Ex: executeSnapshotAction(5, “restore”, new String[] {“restore=DRU1{}”}); //will restore to the default paths for DRU1
    - in the case of an advanced RAID reconfiguration where the reconfiguration script is passed as the extra parameter string
    Ex: executeSnapshotAction(5, “update”, new String[] {“remove|DRU1|E:\”});
    Advanced RAID reconfiguration is always executed as an update. See http://wiki.flexraid.com/2011/10/03/tip-advanced-raid-re-configuration/
    - in removing a drive in a Snapshot CruiseControl configuration, where three parameters are passed
    Ex: executeSnapshotAction(5, “update”, new String[] {“remove|DRU1|E:\”, GUID, newPath}); //where GUID is FileModel.id and newPath is FileModel.oldPath (but can be any mountpoint where to mount the drive after being released from CruiseControl)

  • public ActionStatus executeRealTimeAction(Long configId, String action, String[] extraProperties);
    Where configId is RAIDConfigModel.id and action is either create, verify, force-sync-verify, reconcile, fast-expansion, fast-contraction, or span-update.
    The parameter extraProperties is usually null except for:
    - restore, where an extra string is passed in the form of: restore=DRUx/PPUx{/Path1;/Path2;etc.}
    Ex: executeRealTimeAction(5, “restore”, new String[] {“restore=DRU1{}”}); //will restore to the default paths for DRU1
    - fast-contraction, where three parameters are passed. The first param has the form of: remove=X1;X2;etc.
    Ex: executeRealTimeAction(5, “fast-contraction”, new String[] {“remove=0″, GUID, newPath}); //Will remove DRU1 and will mount to newPath
    - span-update, where three parameters are passed. The first param has the form of: span-remove/span-add=X1:Y1;X2:Y2;etc.
    Where X is the DRU number – 1 and Y is the span number – 1.
    Ex: executeRealTimeAction(5, “span-update”, new String[] {“span-remove=0:0″, GUID, newPath});
  • public ActionStatus executeCommand(String[] args);
    See http://wiki.flexraid.com/category/developer-resources/ for all command topics.
    Ex: executeCommand(new String[]{“pause”}); //can be used for pause/resume/abort

    This command can also be used to send instructions straight to the core service (usually not recommended, but okay in specific instances).

    public ActionStatus executeCommandSync(String[] args); //Same as executeCommand, but synchronous

  • public ActionStatus initStoragePool(RAIDConfigModel o);
    public ActionStatus viewCommand(String INSTANCE_ID, String action);

    For interacting with the storage pool, the above commands should be used.
    With a fresh configuration or after making changes, you should always call initStoragePool.
    After that you can simply call viewCommand with the action of start or stop.

Be Sociable, Share!

Revisions

No comments yet.

Leave a Reply

twenty + 13 =