blob: c6343694012a387e14fa979cf687ecc1f25c18f2 [file] [log] [blame]
/*
* Copyright (c) 2017 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
*/
package org.eclipse.sensinact.gateway.app.manager.internal;
import org.eclipse.sensinact.gateway.api.core.ActionResource;
import org.eclipse.sensinact.gateway.api.core.DataResource;
import org.eclipse.sensinact.gateway.api.core.PropertyResource;
import org.eclipse.sensinact.gateway.app.api.lifecycle.ApplicationStatus;
import org.eclipse.sensinact.gateway.app.api.persistence.ApplicationPersistenceService;
import org.eclipse.sensinact.gateway.app.api.persistence.listener.ApplicationAvailabilityListenerAbstract;
import org.eclipse.sensinact.gateway.app.manager.AppConstant;
import org.eclipse.sensinact.gateway.app.manager.application.ApplicationService;
import org.eclipse.sensinact.gateway.app.manager.osgi.AppServiceMediator;
import org.eclipse.sensinact.gateway.common.primitive.InvalidValueException;
import org.eclipse.sensinact.gateway.core.InvalidResourceException;
import org.eclipse.sensinact.gateway.core.InvalidServiceException;
import org.eclipse.sensinact.gateway.core.InvalidServiceProviderException;
import org.eclipse.sensinact.gateway.core.ModelConfiguration;
import org.eclipse.sensinact.gateway.core.ModelConfigurationBuilder;
import org.eclipse.sensinact.gateway.core.ModelInstance;
import org.eclipse.sensinact.gateway.core.ModelInstanceBuilder;
import org.eclipse.sensinact.gateway.core.ResourceImpl;
import org.eclipse.sensinact.gateway.core.ServiceImpl;
import org.eclipse.sensinact.gateway.core.ServiceProviderImpl;
import org.eclipse.sensinact.gateway.core.method.AccessMethod;
import org.eclipse.sensinact.gateway.core.method.AccessMethodExecutor;
import org.eclipse.sensinact.gateway.core.method.Signature;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This factory create the AppManager service provider and its resources in the admin service.
*
* @author Remi Druilhe
*/
public class AppManagerFactory extends ApplicationAvailabilityListenerAbstract {
private static Logger LOG = LoggerFactory.getLogger(AppManagerFactory.class);
private final ModelInstance<ModelConfiguration> modelInstance;
private final ServiceProviderImpl serviceProvider;
private final AppJsonSchemaListener jsonSchemaListener;
private final ApplicationPersistenceService persistenceService;
private AppInstallExecutor installExecutor;
private AppUninstallExecutor uninstallExecutor;
/**
* Constructor of the AppManager
*
* @param mediator the mediator
* @throws InvalidResourceException
* @throws InvalidServiceProviderException
* @throws InvalidServiceException
* @throws InvalidValueException
*/
public AppManagerFactory(AppServiceMediator mediator, ApplicationPersistenceService persistenceService) throws InvalidResourceException, InvalidServiceProviderException, InvalidServiceException, InvalidValueException {
this.persistenceService = persistenceService;
ModelConfiguration config = new ModelConfigurationBuilder(mediator,
ModelConfiguration.class, ModelInstance.class
).withStartAtInitializationTime(true).build();
this.modelInstance = new ModelInstanceBuilder(mediator).build(
AppConstant.DEVICE_NAME, null, config);
this.modelInstance.configuration().setServiceImplmentationType(ApplicationService.class);
this.serviceProvider = this.modelInstance.getRootElement();
ServiceImpl adminService = this.serviceProvider.getAdminService();
ResourceImpl installResource = adminService.addActionResource(AppConstant.INSTALL, ActionResource.class);
AccessMethod.Type act = AccessMethod.Type.valueOf(AccessMethod.ACT);
installExecutor = new AppInstallExecutor(mediator, this.serviceProvider, persistenceService);
installResource.registerExecutor(new Signature(mediator, act, new Class[]{String.class, JSONObject.class}, null), installExecutor, AccessMethodExecutor.ExecutionPolicy.AFTER);
//installResource.getAccessMethod(act).invoke()
ResourceImpl uninstallResource = adminService.addActionResource(AppConstant.UNINSTALL, ActionResource.class);
uninstallExecutor = new AppUninstallExecutor(mediator, this.serviceProvider, persistenceService);
uninstallResource.registerExecutor(new Signature(mediator, act, new Class[]{String.class}, null), uninstallExecutor, AccessMethodExecutor.ExecutionPolicy.AFTER);
ResourceImpl resource = adminService.addDataResource(PropertyResource.class, AppConstant.KEYWORDS, JSONArray.class, null);
this.jsonSchemaListener = new AppJsonSchemaListener(mediator, resource);
this.persistenceService.registerServiceAvailabilityListener(uninstallExecutor);
this.persistenceService.registerServiceAvailabilityListener(installExecutor);
}
/**
* Uninstall properly the AppManager service provider
*/
public void deleteAppManager() throws Exception {
deleteApplication(null);
modelInstance.unregister();
jsonSchemaListener.stop();
}
/**
* stop and delete application container
*
* @param name name of application to be deleted , or all of them if null
* @throws Exception
*/
public void deleteApplication(String name) throws Exception {
for (ServiceImpl service : serviceProvider.getServices()) {
if (service instanceof ApplicationService) {
ApplicationService applicationContainer = ((ApplicationService) service);
if (name == null || applicationContainer.getApplication().getName().equals(name)) {
applicationContainer.getApplication().stop();
}
}
}
}
private ApplicationService getApplicationService(String name) {
for (ServiceImpl service : serviceProvider.getServices()) {
if (service instanceof ApplicationService) {
ApplicationService applicationContainer = ((ApplicationService) service);
if (name != null && applicationContainer.getApplication().getName().equals(name)) {
return applicationContainer;
}
}
}
return null;
}
@Override
public void applicationFound(String applicationName, String content) {
try {
LOG.info("Installing new application '{}'", applicationName);
installExecutor.install(applicationName, new JSONObject(content).getJSONArray("parameters").getJSONObject(1).getJSONObject("value"));
} catch (Exception e) {
LOG.error("Failed to install application '{}'", applicationName, e);
}
}
@Override
public void applicationChanged(String applicationName, String content) {
try {
LOG.info("Updating application content '{}'", applicationName);
ApplicationService as = getApplicationService(applicationName);
as.getApplication().stop();
as.getResource(AppConstant.STATUS).getAttribute(DataResource.VALUE).setValue(ApplicationStatus.INSTALLED);
as.stop();
installExecutor.install(applicationName, new JSONObject(content).getJSONArray("parameters").getJSONObject(1).getJSONObject("value"));
} catch (Exception e) {
LOG.error("Failed to uninstall application {}", applicationName, e);
}
}
@Override
public void applicationRemoved(String applicationName) {
try {
LOG.info("Removing application '{}'", applicationName);
//deleteApplication(applicationName);
//uninstallExecutor.uninstall(applicationName);
ApplicationService as = getApplicationService(applicationName);
as.getResource(AppConstant.STATUS).getAttribute(DataResource.VALUE).setValue(ApplicationStatus.UNINSTALLED);
as.getApplication().stop();
as.getApplication().uninstall();
as.stop();
} catch (Exception e) {
LOG.error("Failed to uninstall application", applicationName, e);
}
}
}