blob: 0068dadc63a88e3af24398ed667ed333de4dfb82 [file] [log] [blame]
package org.eclipse.sensinact.gateway.core;
import org.eclipse.sensinact.gateway.common.bundle.Mediator;
import org.eclipse.sensinact.gateway.common.execution.Executable;
import org.eclipse.sensinact.gateway.core.method.AccessMethod;
import org.eclipse.sensinact.gateway.core.remote.SensinactCoreBaseIFaceManager;
import org.eclipse.sensinact.gateway.core.security.AccessLevelOption;
import org.eclipse.sensinact.gateway.core.security.AccessNode;
import org.eclipse.sensinact.gateway.core.security.AccessTree;
import org.eclipse.sensinact.gateway.util.UriUtils;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
@SuppressWarnings({"rawtypes","unchecked"})
public final class RegistryEndpoint {
private Mediator mediator;
private final String defaultLocation;
public RegistryEndpoint(Mediator mediator){
this.mediator = mediator;
this.defaultLocation = ModelInstance.defaultLocation(mediator);
}
protected Collection<ServiceReference<SensiNactResourceModel>> getReferences(SessionKey sessionKey, String filter) {
return getReferences(sessionKey.getAccessTree(),filter);
}
protected Collection<ServiceReference<SensiNactResourceModel>> getReferences(AccessTree<? extends AccessNode> tree, String filter) {
AccessMethod.Type describe = AccessMethod.Type.valueOf(AccessMethod.DESCRIBE);
Collection<ServiceReference<SensiNactResourceModel>> result = new ArrayList<ServiceReference<SensiNactResourceModel>>();
Collection<ServiceReference<SensiNactResourceModel>> references = null;
try {
references = mediator.getContext().getServiceReferences(SensiNactResourceModel.class, filter);
Iterator<ServiceReference<SensiNactResourceModel>> iterator = references.iterator();
while (iterator.hasNext()) {
ServiceReference<SensiNactResourceModel> reference = iterator.next();
String name = (String) reference.getProperty("name");
Integer level = (Integer) reference.getProperty(name.concat(".DESCRIBE"));
if (level == null) {
level = Integer.valueOf(AccessLevelOption.OWNER.getAccessLevel().getLevel());
}
AccessNode node = tree.getRoot().get(UriUtils.getUri(new String[] { name }));
if (node == null) {
node = tree.getRoot();
}
if (node.getAccessLevelOption(describe).getAccessLevel().getLevel() >= level.intValue()) {
result.add(reference);
}
}
} catch (InvalidSyntaxException e) {
mediator.error(e.getMessage(), e);
}
return result;
}
public Set<ServiceProvider> serviceProviders(final SessionKey sessionKey, String filter) {
String activeFilter = "(lifecycle.status=ACTIVE)";
String providersFilter = null;
if (filter == null) {
providersFilter = activeFilter;
} else {
StringBuilder filterBuilder = new StringBuilder().append("(&");
if (!filter.startsWith("(")) {
filterBuilder.append("(");
}
filterBuilder.append(filter);
if (!filter.endsWith(")")) {
filterBuilder.append(")");
}
filterBuilder.append(activeFilter);
filterBuilder.append(")");
providersFilter = filterBuilder.toString();
}
final String fltr = providersFilter;
Set<ServiceProvider> serviceProviders = AccessController.<Set<ServiceProvider>>doPrivileged(
new PrivilegedAction<Set<ServiceProvider>>() {
@Override
public Set<ServiceProvider> run() {
Collection<ServiceReference<SensiNactResourceModel>> references =
RegistryEndpoint.this.getReferences(sessionKey, fltr);
Iterator<ServiceReference<SensiNactResourceModel>> iterator =
references.iterator();
Set<ServiceProvider> providers = new HashSet<ServiceProvider>();
while (iterator.hasNext()) {
ServiceReference<SensiNactResourceModel> ref = iterator.next();
SensiNactResourceModel model = mediator.getContext().getService(ref);
ServiceProvider provider = null;
try {
provider = (ServiceProvider) model.getRootElement().getProxy(
sessionKey.getAccessTree());
} catch (ModelElementProxyBuildException e) {
mediator.error(e);
}
if (provider != null && provider.isAccessible())
providers.add(provider);
}
return providers;
}
});
return serviceProviders;
}
public ServiceProvider serviceProvider(SessionKey sessionKey, final String serviceProviderName) {
ServiceProvider provider = null;
Set<ServiceProvider> providers = this.serviceProviders(sessionKey,
new StringBuilder().append("(name=").append(serviceProviderName).append(")").toString());
if (providers == null || providers.size() != 1) {
return provider;
}
provider = providers.iterator().next();
return provider;
}
public Service service(SessionKey sessionKey, String serviceProviderName, String serviceName) {
ServiceProvider serviceProvider = serviceProvider(sessionKey, serviceProviderName);
Service service = null;
if (serviceProvider != null) {
service = serviceProvider.getService(serviceName);
}
return service;
}
public Resource resource(SessionKey sessionKey, String serviceProviderName, String serviceName,
String resourceName) {
Service service = this.service(sessionKey, serviceProviderName, serviceName);
Resource resource = null;
if (service != null)
resource = service.getResource(resourceName);
return resource;
}
public boolean isAccessible(AccessTree<? extends AccessNode> tree, String path) {
String[] uriElements = UriUtils.getUriElements(path);
String providerName = uriElements[0];
String serviceName = uriElements.length>1?uriElements[1]:null;
String resourceName = uriElements.length>2?uriElements[2]:null;
String filter = new StringBuilder().append("(&(name=").append(providerName
).append(")(lifecycle.status=ACTIVE))").toString();
Collection<ServiceReference<SensiNactResourceModel>> references =
this.getReferences(tree, filter);
if(references.size()!=1) {
return false;
}
ServiceReference<SensiNactResourceModel> reference = references.iterator().next();
AccessMethod.Type describe = AccessMethod.Type.valueOf(AccessMethod.DESCRIBE);
AccessNode node = tree.getRoot();
int index = 0;
String pa = null;
String key = null;
Integer inheritedObjectDescribeLevel = Integer.valueOf(
AccessLevelOption.OWNER.getAccessLevel().getLevel());
while(true) {
switch(index) {
case 0:
pa = UriUtils.getUri(new String[] {providerName});
key = providerName.concat(".DESCRIBE");
break;
case 1:
List<String> services = (List<String>) reference.getProperty("services");
if(services == null || !services.contains(serviceName)) {
return false;
}
pa = UriUtils.getUri(new String[] {pa,serviceName});
key = new StringBuilder().append(serviceName).append(".DESCRIBE").toString();
break;
case 2:
List<String> resources = (List<String>) reference.getProperty(serviceName.concat(".resources"));
if(resources == null || !resources.contains(resourceName)) {
return false;
}
pa = UriUtils.getUri(new String[] {pa,resourceName});
key = new StringBuilder().append(serviceName).append(".").append(resourceName).append(".DESCRIBE").toString();
break;
default:
return false;
}
AccessNode tmpNode = tree.getRoot().get(pa);
if (tmpNode == null) {
tmpNode = node;
} else{
node = tmpNode;
}
Integer level = (Integer) reference.getProperty(key);
if(level == null) {
level = inheritedObjectDescribeLevel;
}else {
inheritedObjectDescribeLevel = level;
}
if (node.getAccessLevelOption(describe).getAccessLevel().getLevel() < inheritedObjectDescribeLevel.intValue()) {
return false;
}
if(++index == uriElements.length) {
return true;
}
}
}
public String getAll(SessionKey sessionKey, boolean resolveNamespace, String filter) {
StringBuilder builder = new StringBuilder();
int index = -1;
Collection<ServiceReference<SensiNactResourceModel>> references =
RegistryEndpoint.this.getReferences(sessionKey, filter);
Iterator<ServiceReference<SensiNactResourceModel>> iterator =
references.iterator();
AccessTree<? extends AccessNode> tree = sessionKey.getAccessTree();
AccessMethod.Type describe = AccessMethod.Type.valueOf(AccessMethod.DESCRIBE);
String namespace = namespace();
String prefix = "";
while (iterator.hasNext()) {
index++;
ServiceReference<SensiNactResourceModel> reference = iterator.next();
String name = (String) reference.getProperty("name");
String provider = new StringBuilder().append(prefix).append(name).toString();
String location = null;
Object obj = reference.getProperty(ModelInstanceRegistration.LOCATION_PROPERTY.concat(".value"));
if (obj != null) {
location = String.valueOf(obj).replace('"', '\'');
}
location = (location == null || location.length() == 0) ? defaultLocation : location;
List<String> serviceList = (List<String>) reference.getProperty("services");
builder.append(index > 0 ? ',' : "");
builder.append('{');
builder.append("\"name\":");
builder.append('"');
if(!SensinactCoreBaseIFaceManager.EMPTY_NAMESPACE.equals(namespace) && sessionKey.localID()!=0) {
builder.append(namespace);
builder.append(":");
}
builder.append(provider);
builder.append('"');
if(!SensinactCoreBaseIFaceManager.EMPTY_NAMESPACE.equals(namespace)) {
builder.append(",\"namespace\":");
builder.append('"');
builder.append(namespace);
builder.append('"');
}
builder.append(",\"location\":");
builder.append('"');
builder.append(location);
builder.append('"');
builder.append(",\"services\":");
builder.append('[');
int sindex = 0;
int slength = serviceList == null ? 0 : serviceList.size();
for (; sindex < slength; sindex++) {
String service = serviceList.get(sindex);
String serviceUri = UriUtils.getUri(new String[] { name, service });
Integer serviceLevel = (Integer) reference.getProperty(service.concat(".DESCRIBE"));
if (serviceLevel == null) {
serviceLevel = Integer.valueOf(AccessLevelOption.OWNER.getAccessLevel().getLevel());
}
AccessNode node = sessionKey.getAccessTree().getRoot().get(serviceUri);
if (node == null) {
node = tree.getRoot();
}
int describeAccessLevel = node.getAccessLevelOption(describe).getAccessLevel().getLevel();
int serviceLevelLevel = serviceLevel.intValue();
if (node.getAccessLevelOption(describe).getAccessLevel().getLevel() < serviceLevel.intValue()) {
continue;
}
List<String> resourceList = (List<String>) reference.getProperty(service.concat(".resources"));
builder.append(sindex > 0 ? ',' : "");
builder.append('{');
builder.append("\"name\":");
builder.append('"');
builder.append(service);
builder.append('"');
builder.append(",\"resources\":");
builder.append('[');
int rindex = 0;
int rlength = resourceList == null ? 0 : resourceList.size();
for (; rindex < rlength; rindex++) {
String resource = resourceList.get(rindex);
String resolvedResource = new StringBuilder().append(service).append(".").append(resource).toString();
String resourceUri = UriUtils.getUri(new String[] { name, service, resource });
Integer resourceLevel = (Integer) reference.getProperty(resolvedResource.concat(".DESCRIBE"));
if (resourceLevel == null)
resourceLevel = Integer.valueOf(AccessLevelOption.OWNER.getAccessLevel().getLevel());
node = sessionKey.getAccessTree().getRoot().get(resourceUri);
if (node == null)
node = tree.getRoot();
if (node.getAccessLevelOption(describe).getAccessLevel().getLevel() < resourceLevel.intValue())
continue;
String type = (String) reference.getProperty(resolvedResource.concat(".type"));
String rws = null;
switch(type) {
case "PROPERTY":
case "STATE_VARIABLE":
case "SENSOR":
StringBuilder sbuilder = new StringBuilder();
sbuilder.append(resolvedResource);
sbuilder.append(".");
sbuilder.append(DataResource.VALUE);
sbuilder.append(".");
sbuilder.append(Metadata.MODIFIABLE);
String st = (String) reference.getProperty(sbuilder.toString());
if(st!=null) {
switch(st) {
case "MODIFIABLE":
rws = "RW";
break;
case "FIXED":
case "UPDATABLE":
rws = "RO";
break;
default:
break;
}
}
break;
case "ACTION":
default:
break;
}
builder.append(rindex > 0 ? ',' : "");
builder.append('{');
builder.append("\"name\":");
builder.append('"');
builder.append(resource);
builder.append('"');
builder.append(",\"type\":");
builder.append('"');
builder.append(type);
builder.append('"');
if(rws != null) {
builder.append(",\"rws\":");
builder.append('"');
builder.append(rws);
builder.append('"');
}
builder.append('}');
}
builder.append(']');
builder.append('}');
}
builder.append(']');
builder.append('}');
}
String content = builder.toString();
return content;
}
public String getProviders(SessionKey sessionKey, boolean resolveNamespace, String filter) {
try{
String prefix = resolveNamespace
? new StringBuilder().append(namespace()).append(":").toString()
: "";
Collection<ServiceReference<SensiNactResourceModel>> references = this.getReferences(sessionKey, filter);
Iterator<ServiceReference<SensiNactResourceModel>> iterator = references.iterator();
StringBuilder builder = new StringBuilder();
int index = 0;
while (iterator.hasNext()) {
ServiceReference<SensiNactResourceModel> reference = iterator.next();
String name = (String) reference.getProperty("name");
String provider = new StringBuilder().append(prefix).append(name).toString();
if (index > 0) {
builder.append(",");
}
builder.append('"');
builder.append(provider);
builder.append('"');
index++;
}
String content = builder.toString();
return content;
}catch(Exception e){
e.printStackTrace();
return "";
}
}
protected String namespace() {
String namespace = this.mediator.callService(SensinactCoreBaseIFaceManager.class,
new Executable<SensinactCoreBaseIFaceManager,String>() {
@Override
public String execute(SensinactCoreBaseIFaceManager sensinactCoreBaseIFaceManager) throws Exception {
return sensinactCoreBaseIFaceManager.namespace();
}
}
);
return namespace==null?SensinactCoreBaseIFaceManager.EMPTY_NAMESPACE:namespace;
}
};