164 lines
5.9 KiB
Java
164 lines
5.9 KiB
Java
/*
|
|
* Copyright (c) 2015, 2016 OpenStack Foundation.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
* Designating the host side as the client side and the storlet side
|
|
* as the server side, the IPC between the client and server requires
|
|
* 4 different serialization / de-serialization objects:
|
|
* 1. Serializing client commands (client side)
|
|
* 2. De-srializing client commands (server side)
|
|
* 3. Serializing server response (server side)
|
|
* 4. De-srializing server response (client side)
|
|
* This Java class implements the server side serialization objects:
|
|
* ServerSBusInDatagram
|
|
*/
|
|
package org.openstack.storlet.sbus;
|
|
|
|
import java.io.FileDescriptor;
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
|
|
import org.json.simple.parser.JSONParser;
|
|
import org.json.simple.parser.ParseException;
|
|
import org.json.simple.JSONObject;
|
|
import org.json.simple.JSONArray;
|
|
|
|
public class ServerSBusInDatagram {
|
|
|
|
private int numFDs;
|
|
private FileDescriptor[] fds;
|
|
private String command;
|
|
private HashMap<String, String> params;
|
|
private HashMap<String, HashMap<String, String>>[] metadata;
|
|
private String taskID;
|
|
|
|
private void populateMetadata(HashMap<String, String> dest, JSONObject source) throws ParseException {
|
|
for (Object key : source.keySet()) {
|
|
String strKey = (String)key;
|
|
String strVal = (String)source.get(key);
|
|
dest.put(strKey, strVal);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parses a raw message coming from the wire.
|
|
* The incoming message is constructed by the ClientSBusOutDatagram.
|
|
* The message is structured as follows:
|
|
* Array of file descriptors, already parsed in SBusRawMessage
|
|
* A command related json string of the following structure:
|
|
* {
|
|
* "command": "command encoded as string",
|
|
* "params": { // This element is optional
|
|
* "key1": "value1",
|
|
* ...
|
|
* },
|
|
* "task_id": "task id encoded as string" // This element is optional
|
|
* }
|
|
* File descriptors metadata, encoded as a JSON array with one
|
|
* element per file descriptor. The i'th element in the array
|
|
* consists of the metadata of the i'th element in the file
|
|
* descriptors array:
|
|
* [
|
|
* {
|
|
* "storlets": {
|
|
* "type": "the fd type encoded as string", // Mandatory
|
|
* ... // Additional optional storlets metadata
|
|
* },
|
|
* "storage": {
|
|
* "metadata key1": "metadata value 1",
|
|
* ...
|
|
* }
|
|
* },
|
|
* ...
|
|
* ]
|
|
* All the values in the above JSON elements are strings.
|
|
* Once constructed the class provides all necessary accessors to the parsed
|
|
* fields.
|
|
* @param msg the raw mwssage consisting of the string encoded json formats
|
|
* @see SBusPythonFacade.ClientSBusOutDatagram the python code that serilializes the datagram
|
|
* @see SBusPythonFacade.ServerSBusInDatagram the equivalent python code
|
|
*/
|
|
public ServerSBusInDatagram(final SBusRawMessage msg) throws ParseException {
|
|
this.fds = msg.getFiles();
|
|
numFDs = this.fds == null ? 0 : this.fds.length;
|
|
|
|
JSONObject jsonCmdParams = (JSONObject)(new JSONParser().parse(msg.getParams()));
|
|
this.command = (String)jsonCmdParams.get("command");
|
|
this.params = new HashMap<String, String>();
|
|
if (jsonCmdParams.containsKey("params")) {
|
|
JSONObject jsonParams = (JSONObject)jsonCmdParams.get("params");
|
|
for (Object key : jsonParams.keySet()) {
|
|
this.params.put((String)key, (String)jsonParams.get(key));
|
|
}
|
|
}
|
|
if (jsonCmdParams.containsKey("task_id")) {
|
|
this.taskID = (String)jsonCmdParams.get("task_id");
|
|
}
|
|
|
|
String strMD = msg.getMetadata();
|
|
this.metadata = (HashMap<String, HashMap<String, String>>[])new HashMap[getNFiles()];
|
|
JSONArray jsonarray = (JSONArray)(new JSONParser().parse(strMD));
|
|
Iterator<JSONObject> it = jsonarray.iterator();
|
|
int i=0;
|
|
while (it.hasNext()) {
|
|
this.metadata[i] = new HashMap<String, HashMap<String, String>>();
|
|
HashMap<String, String> storletsMetadata = new HashMap<String, String>();
|
|
HashMap<String, String> storageMetadata = new HashMap<String, String>();
|
|
JSONObject jsonobject = it.next();
|
|
if (jsonobject.containsKey("storage")) {
|
|
populateMetadata(storageMetadata, (JSONObject)jsonobject.get("storage"));
|
|
}
|
|
if (!jsonobject.containsKey("storlets")) {
|
|
}
|
|
else {
|
|
populateMetadata(storletsMetadata, (JSONObject)jsonobject.get("storlets"));
|
|
}
|
|
this.metadata[i].put("storage", storageMetadata);
|
|
this.metadata[i].put("storlets", storletsMetadata);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
public FileDescriptor[] getFiles() {
|
|
return fds;
|
|
}
|
|
|
|
public int getNFiles() {
|
|
return numFDs;
|
|
}
|
|
|
|
public String getCommand() {
|
|
return command;
|
|
}
|
|
|
|
public HashMap<String, String> getExecParams() {
|
|
return params;
|
|
}
|
|
|
|
public String getTaskId() {
|
|
return taskID;
|
|
}
|
|
|
|
public HashMap<String, HashMap<String, String>>[] getFilesMetadata() {
|
|
return metadata;
|
|
}
|
|
}
|