blob: 4b55c5868f11b40b61235f8cda1615ecb9fdf3ea [file] [log] [blame]
/**
* Copyright (c) 2018 CEA.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* CEA - initial API and implementation and/or initial documentation
*/
package org.eclipse.sensinact.studio.http.services.client.agent;
import java.io.IOException;
import java.util.List;
import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
import org.eclipse.sensinact.studio.http.messages.snamessage.subscriberesponse.MsgSubscribeResponse;
import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient;
import org.eclipse.sensinact.studio.model.resource.utils.Segments;
import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
import org.eclipse.sensinact.studio.preferences.StudioHttpConfig;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.restlet.data.Status;
/**
* @author Etienne Gandrille
*/
public class Agent {
private static Agent INSTANCE = null;
private SubscriptionStorage storage = new SubscriptionStorage();
private Agent() {
}
public static Agent getInstance() {
if (INSTANCE == null)
INSTANCE = new Agent();
return INSTANCE;
}
public void subscribe(GatewayHttpConfig gateway) throws JSONException, IOException {
String gatewayName = gateway.getName();
Segments segments = new Segments.BuilderGateway(gatewayName).subscribeAgent().build();
String url = getCallbackUrl(gateway);
String locId = getId(GatewayHttpClient.sendPostRequest(segments, createJsonForLocation(url)), url);
String lcId = getId(GatewayHttpClient.sendPostRequest(segments, createJsonForLifecycle(url)), url);
String icId = getId(GatewayHttpClient.sendPostRequest(segments, createJsonForIcon(url)), url);
storage.add(new Subscription(gatewayName, locId, lcId, icId));
}
public void unsubscribe(GatewayHttpConfig gateway) throws IOException, JSONException {
String gatewayName = gateway.getName();
Segments segments = new Segments.BuilderGateway(gatewayName).unsubscribeAgent().build();
Subscription subscription = storage.getByGateway(gateway.getName());
if (subscription == null) {
throw new IllegalArgumentException("Can't get subscription for " + gatewayName);
}
GatewayHttpClient.sendPostRequest(segments, createJsonForUnscubscribe(subscription.getLocationId()));
GatewayHttpClient.sendPostRequest(segments, createJsonForUnscubscribe(subscription.getLifecycleId()));
storage.remove(subscription);
}
private static String getId(MsgSensinact msg, String url) {
if (msg instanceof MsgSubscribeResponse)
return ((MsgSubscribeResponse) msg).getResponse().getSubscriptionId();
throw new IllegalArgumentException("Can't get subscription on " + url);
}
private static String getCallbackUrl(GatewayHttpConfig gateway) throws IOException {
int port = ConfigurationManager.getStudioPort();
StudioHttpConfig studioConfig = new StudioHttpConfig(gateway, port);
String url = studioConfig.getUrl().toString();
if (url == null || url.isEmpty())
throw new IOException("URL is not valid - subscribtion fail");
// TODO update this with a constant --> see also InitRoutes.java
url += "/callback";
return url;
}
private static JSONArray createJsonForLocation(String url) throws JSONException {
return createJson(url, "/[^/]+/admin/location(/[^/]+)?", "UPDATE");
}
private static JSONArray createJsonForIcon(String url) throws JSONException {
return createJson(url, "/[^/]+/admin/icon(/[^/]+)?", "UPDATE");
}
private static JSONArray createJsonForLifecycle(String url) throws JSONException {
return createJson(url, "(/[^/]+)+", "LIFECYCLE");
}
private static JSONArray createJsonForUnscubscribe(String subscriptionid) throws JSONException {
JSONArray array = new JSONArray();
array.put(nameTypeValue("subscriptionId", "string", subscriptionid));
return array;
}
private static JSONArray createJson(String url, String sender, String type) throws JSONException {
JSONArray array = new JSONArray();
array.put(nameTypeValue("sender", "string", sender));
array.put(nameTypeValue("pattern", "boolean", "true"));
array.put(nameTypeValue("complement", "boolean", "false"));
array.put(nameTypeValue("types", "array", "[\"" + type + "\"]"));
array.put(nameTypeValue("callback", "string", url));
return array;
}
private static JSONObject nameTypeValue(String name, String type, String value) throws JSONException {
JSONObject retval = new JSONObject();
retval.put("name", name);
retval.put("type", type);
retval.put("value", value);
return retval;
}
public boolean isConnected(String name) {
return (storage.getByGateway(name) != null);
}
public Status callbackRecieved(String id, List<MsgSensinact> messages) {
Subscription lifeSub = storage.getByLifecycleId(id);
Subscription locSub = storage.getByLocationId(id);
Subscription locIcon = storage.getByIconId(id);
if (lifeSub != null) {
String gateway = lifeSub.getGatewayName();
SubscriptionManager.getInstance().notifyLifecycle(gateway, messages);
return Status.SUCCESS_OK;
}
if (locSub != null) {
String gateway = locSub.getGatewayName();
SubscriptionManager.getInstance().notifyLocation(gateway, messages);
return Status.SUCCESS_OK;
}
if (locIcon != null) {
String gateway = locIcon.getGatewayName();
SubscriptionManager.getInstance().notifyLocation(gateway, messages);
return Status.SUCCESS_OK;
}
return Status.CLIENT_ERROR_NOT_FOUND;
}
}