Service mavenization completed

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/vre-management/ResourceManager@55388 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Manuele Simi 2012-05-31 20:25:31 +00:00
parent a4cf8edb60
commit 1b406bfc6f
71 changed files with 8200 additions and 14 deletions

View File

@ -1,9 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/GCORELIBS"/>
<classpathentry combineaccessrules="false" kind="src" path="/gcf.TRUNK"/>
<classpathentry kind="lib" path="/Dependencies/RMDeps/org.gcube.vremanagement.resourcemanager.stubs.jar"/>
<classpathentry kind="lib" path="/Dependencies/RMDeps/softwaregateway-stubs-1.0.0-SNAPSHOT.jar"/>

11
INSTALL
View File

@ -1,11 +0,0 @@
to compile:
ant garService
ant buildStubs
to deploy:
gcore-deploy-service org.gcube.vremanagement.resourcemanager.gar
cp org.gcube.vremanagement.resourcemanager.stubs.jar

9
config/build.properties Executable file
View File

@ -0,0 +1,9 @@
package = org.gcube.vremanagement.resourcemanager
lib.dir = Dependencies/ResourceManager
wsdl.1 = ResourceManager
package.1 = resourcemanager
package.2 = common
namespace.1=http://gcube-system.org/namespaces/vremanagement/resourcemanager
namespace.2=http://gcube-system.org/common/vremanagement/types

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<jndiConfig xmlns="http://wsrf.globus.org/jndi/config">
<service name="gcube/vremanagement/ResourceManager/service">
<environment
name="configDir"
value="@config.dir@"
type="java.lang.String"
override="false" />
<environment
name="resourceBrokerClass"
value="org.gcube.vremanagement.resourcemanager.impl.brokerage.ServiceBroker"
type="java.lang.String"
override="false" />
<!--
<environment
name="startScopes"
value=""
type="java.lang.String"
override="false" /> -->
</service>
<service name="gcube/vremanagement/ResourceManager">
<environment
name="name"
value="ResourceManager"
type="java.lang.String"
override="false" />
<resource name="home" type="org.gcube.vremanagement.resourcemanager.impl.state.ResourceManagerHome">
<resourceParams>
<parameter>
<name>factory</name>
<value>org.globus.wsrf.jndi.BeanFactory</value>
</parameter>
<parameter>
<name>resourceClass</name>
<value>org.gcube.vremanagement.resourcemanager.impl.state.InstanceState</value>
</parameter>
</resourceParams>
</resource>
</service>
</jndiConfig>

17
config/deploy-server.wsdd Normal file
View File

@ -0,0 +1,17 @@
<deployment name="defaultServerConfig"
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<service name="gcube/vremanagement/ResourceManager" provider="Handler" use="literal" style="document">
<parameter name="className" value="org.gcube.vremanagement.resourcemanager.impl.ResourceManager"/>
<wsdlFile>share/schema/org.gcube.vremanagement.resourcemanager/ResourceManager_service.wsdl</wsdlFile>
<parameter name="allowedMethods" value="*"/>
<parameter name="handlerClass" value="org.globus.axis.providers.RPCProvider"/>
<parameter name="scope" value="Application"/>
<parameter name="providers" value="GCUBEProvider GetCurrentMessageProvider"/>
<parameter name="loadOnStartup" value="true"/>
<parameter name="securityDescriptor" value="@config.dir@/security_descriptor.xml"/>
</service>
</deployment>

50
config/profile.xml Normal file
View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<Resource>
<ID/>
<Type>Service</Type>
<Profile>
<Description>ResourceManager creates and manages a VRE context</Description>
<Class>VREManagement</Class>
<Name>ResourceManager</Name>
<Version>1.0.0</Version>
<Packages>
<Main deployable="true">
<Description>ResourceManager creates and manages Scopes within a gCube infrastructure</Description>
<Name>ResourceManager-service</Name>
<Version>1.2.0-SNAPSHOT</Version>
<Mandatory level="VRE"/>
<Shareable level="NONE"/>
<GHNRequirements/>
<GARArchive>org.gcube.vremanagement.resourcemanager.gar</GARArchive>
<PortType>
<Name>gcube/vremanagement/ResourceManager</Name>
<Security/>
<WSDL/>
</PortType>
</Main>
<Software>
<Description>Stubs for ResourceManager: provide facilities to interact with a ResourceManager instance</Description>
<Name>ResourceManager-stubs</Name>
<Version>1.2.0-SNAPSHOT</Version>
<MultiVersion value="true"/>
<Mandatory level="GHN"/>
<Shareable level="VO"/>
<Type>library</Type>
<Files>
<File>org.gcube.vremanagement.resourcemanager.stubs.jar</File>
</Files>
</Software>
<Software>
<Description>Test-suite for ResourceManager: provide sample usages of interaction with a ResourceManager instance</Description>
<Name>ResourceManager-test-suite</Name>
<Version>1.2.0-SNAPSHOT</Version>
<MultiVersion value="true"/>
<Shareable level="VO"/>
<Type>application</Type>
<Files>
<File>lib/org.gcube.vremanagement.resourcemanager.testsuite.jar</File>
</Files>
</Software>
</Packages>
</Profile>
</Resource>

1
config/reports/readme.txt Executable file
View File

@ -0,0 +1 @@
This folder contains the resource reports.

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<securityConfig xmlns="http://www.globus.org" >
<authz value="none"/>
<method name="addResources">
<auth-method>
<none/>
</auth-method>
</method>
<method name="sendReport">
<auth-method>
<none/>
</auth-method>
</method>
<method name="setScopeOptions">
<auth-method>
<none/>
</auth-method>
</method>
<method name="getReport">
<auth-method>
<none/>
</auth-method>
</method>
<method name="removeResources">
<auth-method>
<none/>
</auth-method>
</method>
<method name="notifyGHNdeath">
<auth-method>
<none/>
</auth-method>
</method>
<method name="queryResourceProperties">
<auth-method>
<none/>
</auth-method>
</method>
<method name="subscribe">
<auth-method>
<none/>
</auth-method>
</method>
<method name="getCurrentMessage">
<auth-method>
<none/>
</auth-method>
</method>
<method name="getMultipleResourceProperties">
<auth-method>
<none/>
</auth-method>
</method>
</securityConfig>

3
distro/INSTALL Normal file
View File

@ -0,0 +1,3 @@

70
distro/descriptor.xml Normal file
View File

@ -0,0 +1,70 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>servicearchive</id>
<formats>
<format>tar.gz</format>
</formats>
<baseDirectory>/</baseDirectory>
<fileSets>
<fileSet>
<directory>${distroDirectory}</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
<includes>
<include>README</include>
<include>LICENSE</include>
<include>INSTALL</include>
<include>MAINTAINERS</include>
<include>changelog.xml</include>
</includes>
<fileMode>755</fileMode>
<filtered>true</filtered>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<includes>
<include>*:resource-manager-stubs</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveDependencies>false</useTransitiveDependencies>
<outputDirectory>resource-manager-stubs</outputDirectory>
</dependencySet>
<dependencySet>
<includes>
<include>*:resource-manager-test-suite</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveDependencies>false</useTransitiveDependencies>
<outputDirectory>resource-manager-test-suite</outputDirectory>
</dependencySet>
</dependencySets>
<files>
<file>
<source>${configDirectory}/profile.xml</source>
<outputDirectory></outputDirectory>
<filtered>true</filtered>
</file>
<file>
<source>target/${build.finalName}.gar</source>
<outputDirectory>${project.artifactId}</outputDirectory>
</file>
<file>
<source>${distroDirectory}/svnpath.txt</source>
<outputDirectory>${project.artifactId}</outputDirectory>
<filtered>true</filtered>
</file>
<file>
<source>${distroDirectory}/svnpath.txt</source>
<outputDirectory>resource-manager-stubs</outputDirectory>
<filtered>true</filtered>
</file>
<file>
<source>${distroDirectory}/svnpath.txt</source>
<outputDirectory>resource-manager-test-suite</outputDirectory>
<filtered>true</filtered>
</file>
</files>
</assembly>

1
distro/svnpath.txt Normal file
View File

@ -0,0 +1 @@
${scm.url}

77
pom.xml Normal file
View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>maven-parent</artifactId>
<groupId>org.gcube.tools</groupId>
<version>1.0.0</version>
<relativePath />
</parent>
<groupId>org.gcube.resourcemanagement</groupId>
<artifactId>resource-manager</artifactId>
<version>1.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Resource Manager Reactor</name>
<modules>
<!-- The repository module must be first in order to ensure
that the local repository is populated -->
<module>resource-manager-stubs</module>
<module>resource-manager-service</module>
<module>resource-manager-test-suite</module>
</modules>
<properties>
<wsdlDirectory>${project.basedir}/../wsdl</wsdlDirectory>
<wsdlOutputDirectory>${project.basedir}/../target/generated-sources/wsdl</wsdlOutputDirectory>
<configDirectory>${project.basedir}/../config</configDirectory>
<distroDirectory>${project.basedir}/../distro</distroDirectory>
<namespace>http://gcube-system.org/namespaces/vremanagement/resourcemanager</namespace>
<basepackage>org.gcube.vremanagement.resourcemanager</basepackage>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>gcf</artifactId>
<version>[1.4.0-SNAPSHOT,1.5.0-SNAPSHOT)</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<!-- defines basic configuration for the service plugin -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.gcube.tools</groupId>
<artifactId>maven-service-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<serviceId>deployer</serviceId>
<basePackage>${basepackage}</basePackage>
<wsdlDirectory>${wsdlDirectory}</wsdlDirectory>
<wsdlOutputDirectory>${wsdlOutputDirectory}</wsdlOutputDirectory>
<configurationDirectory>${configDirectory}</configurationDirectory>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1,209 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.gcube.resourcemanagement</groupId>
<artifactId>resource-manager</artifactId>
<version>1.2.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>resource-manager-service</artifactId>
<name>Resource Manager Service</name>
<description>A service for managing subsets of gCube resources in a given scope</description>
<scm>
<connection>scm:svn:http://svn.d4science.research-infrastructures.eu/gcube/trunk/vre-management/ResourceManager</connection>
<developerConnection>scm:svn:https://svn.d4science.research-infrastructures.eu/gcube/trunk/vre-management/ResourceManager</developerConnection>
<url>http://svn.d4science.research-infrastructures.eu/gcube/trunk/vre-management/ResourceManager</url>
</scm>
<dependencies>
<!-- reactor dependencies -->
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>gcf</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.resourcemanagement</groupId>
<artifactId>resource-manager-stubs</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.gcube.resourcemanagement</groupId>
<artifactId>softwaregateway-stubs</artifactId>
<version>[1.0.0-SNAPSHOT,1.1.0-SNAPSHOT)</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.vremanagement</groupId>
<artifactId>ghnmanager-stubs</artifactId>
<version>[1.5.0-SNAPSHOT,1.6.0-SNAPSHOT)</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.vremanagement</groupId>
<artifactId>resourcebroker-serialization</artifactId>
<version>[1.2.0-SNAPSHOT,1.3.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.vremanagement</groupId>
<artifactId>resourcebroker-stubs</artifactId>
<version>[1.2.0-SNAPSHOT,1.3.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.resourcemanagement</groupId>
<artifactId>deployer-stubs</artifactId>
<version>[2.3.0-SNAPSHOT,2.4.0-SNAPSHOT)</version>
<scope>provided</scope>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>org.gcube.tools</groupId>
<artifactId>my-container</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>local-deploy</id>
<build>
<plugins>
<plugin>
<groupId>org.gcube.tools</groupId>
<artifactId>maven-service-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>local-deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<!-- builds Gar at install time -->
<plugin>
<groupId>org.gcube.tools</groupId>
<artifactId>maven-service-plugin</artifactId>
<executions>
<execution>
<id>make-gar</id>
<goals>
<goal>gar-gen</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- downloads my-container when needed -->
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>install-my-container</id>
<phase>generate-test-resources</phase>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.gcube.tools</groupId>
<artifactId>my-container</artifactId>
<version>1.0.0</version>
<type>tar.gz</type>
<classifier>distro</classifier>
<overWrite>false</overWrite>
<outputDirectory>${project.basedir}</outputDirectory>
</artifactItem>
</artifactItems>
<markersDirectory>${project.basedir}</markersDirectory>
</configuration>
<goals>
<goal>unpack</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- generates service archive -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<configuration>
<descriptors>
<descriptor>${distroDirectory}/descriptor.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>servicearchive</id>
<phase>install</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- the following is to allow test-suite sources to access protected methods -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>process-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,327 @@
package org.gcube.vremanagement.resourcemanager.impl;
import java.util.HashSet;
import java.util.Set;
import org.apache.axis.components.uuid.UUIDGenFactory;
import org.gcube.common.core.contexts.GCUBEServiceContext;
import org.gcube.common.core.faults.GCUBEFault;
import org.gcube.common.core.porttypes.GCUBEPortType;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.scope.GCUBEScopeNotSupportedException;
import org.gcube.common.core.scope.GCUBEScope.MalformedScopeExpressionException;
import org.gcube.common.core.scope.GCUBEScopeManager.IllegalScopeException;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.contexts.StatefulPortTypeContext;
import org.gcube.vremanagement.resourcemanager.impl.deployment.DeployerReport;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNodeManager;
import org.gcube.vremanagement.resourcemanager.impl.deployment.DeployerReport.DeployedRunningInstance;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.AddResourcesParameters;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.CreateScopeParameters;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.DisposeScopeParameters;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.InvalidOptionsFaultType;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.InvalidScopeFaultType;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.NoSuchReportFaultType;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.OptionsParameters;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.RemoveResourcesParameters;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ResourcesCreationFaultType;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ResourcesRemovalFaultType;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ScopeOption;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.SendReportParameters;
import org.gcube.vremanagement.resourcemanager.impl.operators.AddResourcesOperator;
import org.gcube.vremanagement.resourcemanager.impl.operators.DisposeScopeOperator;
import org.gcube.vremanagement.resourcemanager.impl.operators.OperatorConfig;
import org.gcube.vremanagement.resourcemanager.impl.operators.RemoveResourcesOperator;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
import org.gcube.vremanagement.resourcemanager.impl.state.PublishedScopeResource;
import org.gcube.vremanagement.resourcemanager.impl.state.InstanceState;
import org.gcube.vremanagement.resourcemanager.impl.state.PublishedScopeResource.UnknownScopeOptionException;
import org.gcube.vremanagement.resourcemanager.impl.state.Session.OPERATION;
import org.globus.wsrf.NoSuchResourceException;
import org.globus.wsrf.ResourceException;
/**
* <em>ResourceManager</em> port-type implementation
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class ResourceManager extends GCUBEPortType {
/** Singleton resource name*/
public static final String SINGLETON_RESOURCE_KEY = "VREManagerState";
/**
* Object logger.
*/
protected final GCUBELog logger = new GCUBELog(this, ServiceContext.getContext());
@Override
protected GCUBEServiceContext getServiceContext() {
return ServiceContext.getContext();
}
/**
* Adds a new group of {@link ScopedResource}s to the managed Scope
*
* @param resourcesList the resources to join
* @return the ID assigned to the operation, it can be used to retrieve the resource session by invoking the {@link ResourceManager#getReport(String)} operation
* @throws GCUBEFault if the operation fails
*/
public synchronized String addResources(AddResourcesParameters resourceList) throws ResourcesCreationFaultType, GCUBEFault {
logger.debug("AddResources operation invoked in scope " + ServiceContext.getContext().getScope().getName());
try {
//checks the input scope
GCUBEScope targetScope = this.validateOperationScope(resourceList.getTargetScope());
Session report = new Session(UUIDGenFactory.getUUIDGen().nextUUID(),OPERATION.AddResources, targetScope);
this.getResource().addSession(report);
new AddResourcesOperator(new OperatorConfig(report, this.getResource().getResourceList(), targetScope),resourceList).run();
//resource.publish();
//returns the session ID, it can be used to invoke the getReport operation
return report.getId();
} catch (IllegalScopeException ise){
logger.error("The target scope (" + resourceList.getTargetScope() + ") is not valid or null or not joined to this instance", ise);
throw ServiceContext.getContext().getDefaultException("The target scope (" + resourceList.getTargetScope() + ") is not valid or null or not joined to this instance", ise).toFault();
} catch (Exception e) {
logger.error("Unable to manage the input given resources(s) within the scope: " + e.getMessage(), e);
throw ServiceContext.getContext().getDefaultException("Unable to manage the input given resources(s) within the scope: " + e.getMessage(), e).toFault();
}
}
/**
* Removes a group of {@link ScopedResource}s from the managed Scope
*
* @param resourcesList the resources to remove from the PublishedScopeResource
* @throws GCUBEFault if the operation fails
*/
public synchronized String removeResources(RemoveResourcesParameters resourceList) throws ResourcesRemovalFaultType, InvalidScopeFaultType {
try {
GCUBEScope targetScope = this.validateOperationScope(resourceList.getTargetScope());
Session report = new Session(UUIDGenFactory.getUUIDGen().nextUUID(), OPERATION.RemoveResources, targetScope);
this.getResource().addSession(report);
new RemoveResourcesOperator(new OperatorConfig(report, this.getResource().getResourceList(), targetScope),resourceList).run();
return report.getId();
} catch (IllegalScopeException ise){
logger.error("The target scope (" + resourceList.getTargetScope() + ") is not valid or null or not joined to this instance", ise);
throw new InvalidScopeFaultType();
} catch (Exception e) {
logger.error("Unable to manage the input given resources(s) within the scope: " + e.getMessage(), e);
//throw ServiceContext.getContext().getDefaultException("Unable to manage the input given resources(s) within the scope: " + e.getMessage(), e).toFault();
throw new ResourcesRemovalFaultType();
}
}
/**
* Disposes the managed Scope
* @param params
* @return
* @throws GCUBEFault
*/
public synchronized String disposeScope(DisposeScopeParameters params) throws InvalidScopeFaultType, GCUBEFault {
logger.info("Dispose Scope invoked... the entire scope is going to be thrown away!!");
try {
GCUBEScope.getScope(params.getName()).getServiceMap();
} catch (MalformedScopeExpressionException e) {
logger.error("Invalid scope expression " + params.getName());
throw new InvalidScopeFaultType();
} catch (GCUBEScopeNotSupportedException e) {
logger.error("Scope not supported " + params.getName());
throw new InvalidScopeFaultType();
}
try {
Session report = new Session(UUIDGenFactory.getUUIDGen().nextUUID(), OPERATION.Dispose,GCUBEScope.getScope(params.getName()));
this.getResource().addSession(report);
new DisposeScopeOperator(new OperatorConfig(report, this.getResource().getResourceList(), GCUBEScope.getScope(params.getName()))).run();
this.getResource().getPublishedScopeResource().dismiss();
return report.getId();
} catch (NoSuchResourceException e) {
logger.error("No resource found for this scope", e);
throw ServiceContext.getContext().getDefaultException("No resource found for this scope", e).toFault();
} catch (Exception e) {
logger.error("Unable to dispose the scope: " + e.getMessage(), e);
throw ServiceContext.getContext().getDefaultException("Unable to dispose the scope: " + e.getMessage(), e).toFault();
}
}
public synchronized String createScope(CreateScopeParameters params)
throws InvalidScopeFaultType, InvalidOptionsFaultType, ResourcesCreationFaultType, GCUBEFault {
String name = params.getName();
logger.info("Creating the new Scope " + name);
try {
GCUBEScope.getScope(name).getServiceMap();
} catch (MalformedScopeExpressionException e) {
throw new InvalidScopeFaultType();
} catch (GCUBEScopeNotSupportedException e) {
//the service map for this scope does not exist
params.getServiceMap();
}
//String map = params.getServiceMap();
this.changeScopeOptions(params.getOptionsParameters());
return this.addResources(params.getAddResourcesParameters());
}
/**
* Changes some options on the scope
*
* @param options the new options to change
* @throws GCUBEFault if any of the input options is not valid
*/
public void changeScopeOptions(OptionsParameters options) throws InvalidOptionsFaultType, InvalidOptionsFaultType, GCUBEFault {
PublishedScopeResource scoperesource = null;
try {
scoperesource = this.getResource().getPublishedScopeResource();
} catch (NoSuchResourceException e) {
logger.error("No resource found for this scope", e);
throw ServiceContext.getContext().getDefaultException("No resource found for this scope", e).toFault();
} catch (Exception e) {
logger.error("Change Scope Options fault: ", e);
throw ServiceContext.getContext().getDefaultException("Change Scope Options fault: ", e).toFault();
}
//add the new options
for (ScopeOption option : options.getScopeOptionList()) {
if (option == null) continue;
logger.trace("ScopeOption received: " + option.getName() +"="+ option.getValue());
try {
scoperesource.setOption(option.getName().trim(), option.getValue().trim());
} catch (UnknownScopeOptionException e) {
logger.warn("Unknown option: " + option.getName());
throw new InvalidOptionsFaultType();
} catch (Exception e) {
logger.warn("Unable to read option: " + option.getName());
throw new InvalidOptionsFaultType();
}
}
//and publish the scope resource
try {
scoperesource.publish();
} catch (Exception e) {
logger.error("Unable to publish the ScopeResouce", e);
throw ServiceContext.getContext().getDefaultException("Unable to publish the ScopeResouce", e).toFault();
}
}
/**
* Receives a deployment session. It is called by the Deployer services on the GHNs contacted within the {@link #addResources(AddResourcesParameters)}
* operation
*
* @param session the resource session
* @throws GCUBEFault if the session does not have a valid serialization
*/
public void sendReport(SendReportParameters reportMessage) throws GCUBEFault {
logger.info("Received session for session " + reportMessage.getCallbackID());
logger.trace("Report content: \n" + reportMessage.getReport());
try {
Session session = this.getResource().getSession(reportMessage.getCallbackID());
DeployerReport dreport = new DeployerReport(reportMessage.getReport());
session.addGHNReport(dreport);
session.save();
PublishedScopeResource resource = this.getResource().getPublishedScopeResource();
logger.debug("Status session is: " + dreport.getStatus());
if (dreport.getStatus().compareToIgnoreCase("CLOSED") == 0) {
logger.trace("Setting the gHN " + dreport.getGHNID() + " as non working");
//if the session is closed, declare the node as "non working" node
VirtualNodeManager.getNode(dreport.getGHNID(), this.getResource().getManagedScope()).isNotWorking();
logger.trace("Parsing running instances (if any)...");
Set<ScopedResource> resources = new HashSet<ScopedResource>();
for (DeployedRunningInstance instance : dreport.getInstances()) {
if (instance.isAlive()) {
logger.trace("Adding instance " + instance.getRIID() + " to PublishedScopeResource");
resource.addResource(instance.getInstance());
resources.add((ScopedResource)instance.getInstance());
} else {
logger.warn("Instance " + instance.getRIID() + " not found on the IS");
}
}
session.addDeployedInstances(dreport.getInstances());
//add the newly generated RIs to the Scope State
this.getResource().getResourceList().addResources(resources);
}
resource.publish();
session.save();
// //send feedback to the broker if needed
// if ((session.isReportClosed()
// && ((session.getOperation()==OPERATION.AddResources)
// || (session.getOperation()==OPERATION.UpdateResources)
// || (session.getOperation()==OPERATION.Create)))) {
// this.updateBroker(session);
// }
} catch (NoSuchResourceException e) {
logger.error("Unable to find ResourceManager resource", e);
throw ServiceContext.getContext().getDefaultException("Unable to find ResourceManager resource", e).toFault();
} catch (ResourceException e) {
logger.error("Unable to find ResourceManager resource", e);
throw ServiceContext.getContext().getDefaultException("Unable to find ResourceManager resource", e).toFault();
} catch (Exception e) {
throw ServiceContext.getContext().getDefaultException("Unable to parse or save the Deployer Report", e).toFault();
}
}
/**
* Gets a Resource Report
*
* @param ID the session identifier
* @return the string serialization of the session
* @throws GNoSuchReportFaultTypeCUBEFault if the session is not found or does not have a valid serialization
*/
public String getReport(String ID) throws NoSuchReportFaultType {
try {
return this.getResource().getSession(ID).toXML();
} catch (Exception e) {
logger.error("Unable to retrieve the Resource Report for ID " + ID,e);
throw new NoSuchReportFaultType();
}
}
// /**
// * Sends the feedback on the deployment activity to the Broker
// * @param services the Resource Report
// * @param reports
// */
// private void updateBroker(Session session) {
// if (session.getServices().size()>0) {
// try {
// logger.info("Sending feedback to the Broker");
// BrokerConnector.getBroker(this.getResource().getManagedScope()).sendFeedback(session);
// } catch (Exception e) {
// logger.error("Can't send feedback to the Broker", e);
// }
// }
// }
/**
* Validates the input scope of each PublishedScopeResource operation
*
* @param inScope the scope to check
* @return the accepted scope
* @throws IllegalScopeException if the given scope has not been accepted
*/
private GCUBEScope validateOperationScope(String inScope) throws IllegalScopeException {
if ((inScope == null) || (inScope.compareToIgnoreCase("") == 0))
return ServiceContext.getContext().getScope(); // use the instance scope as default
else if (GCUBEScope.getScope(inScope.trim()).isEnclosedIn(ServiceContext.getContext().getScope()))
return GCUBEScope.getScope(inScope.trim());
else
throw new IllegalScopeException();
}
/**
* Gets the singleton resource
*
* @return the {@link InstanceState}
* @throws NoSuchResourceException
* @throws ResourceException
*/
private InstanceState getResource() throws NoSuchResourceException, ResourceException{
return (InstanceState) StatefulPortTypeContext.getContext().getWSHome().find(StatefulPortTypeContext.getContext().makeKey(SINGLETON_RESOURCE_KEY));
}
}

View File

@ -0,0 +1,43 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
/**
*
* Models the expected behavior of a Broker.
* A Broker is an entity that can create Deployment Plans for a set of {@link ScopedDeployedService}s to be deployed
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public interface Broker {
/**
* Initializes the Broker instance
* @param scope the scope where the broker will act
* @throws Exception if the initialization fails (depends on the broker's nature)
*/
public void initialize(GCUBEScope scope) throws Exception;
/**
* Creates a deployment plan for the given services
* @param session the current session
* @param services the services to deploy
* @param suggestedGHNs the (eventually) GHNs suggested for the deployment, if specified, only these nodes will be used by the planner
* @throws Exception if the preparation of the plan fails
*/
public void makePlan(Session session, Set<ScopedDeployedService> services, String[] suggestedGHNs) throws Exception;
/**
* Sends feedback to the broker about the execution of the plan for the given session
* @param session the current session
* @throws Exception if the broker is not able to manage the feedback
*/
public void sendFeedback(Session session) throws Exception;
}

View File

@ -0,0 +1,60 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage;
import java.lang.reflect.Constructor;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
/**
* Locates and initializes the Broker to use for services' deployment. A Broker is a component capable to create a plan
* for allocating gCube packages to gHNs
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class BrokerConnector {
private static final String DEFAULT_BROKER = "org.gcube.vremanagement.resourcemanager.impl.brokerage.InternalBroker";
private static final GCUBELog logger = new GCUBELog(BrokerConnector.class);
/**
* Returns the broker to use in the given scope
* @param scope
* @return
* @throws Exception
*/
public static Broker getBroker(GCUBEScope scope) throws Exception {
Broker broker = null;
try {
broker = load((String) ServiceContext.getContext().getProperty("resourceBrokerClass", true));
} catch (Exception e) {
logger.error("Unable to load the configured broker", e);
try {
logger.info("Trying to load the internal broker");
broker = load(DEFAULT_BROKER);
} catch (Exception e1) {
logger.error("Unable to load the internal broker", e1);
throw new Exception("unable to find a broker to use");
}
}
if (broker != null) broker.initialize(scope);
return broker;
}
/**
* Loads a broker instance
* @param className the full name of the Class implementing the broker to load
* @return the broker instance
* @throws Exception
*/
private static Broker load(String className) throws Exception {
if (className==null) return null;
Class<?> clazz = (Class<?>) Class.forName(className);
if (!Broker.class.isAssignableFrom(clazz))
throw new Exception(className+" does not implement "+Broker.class.getName());
Constructor<?> constructor = clazz.getConstructor(new Class[] {});
return (Broker) constructor.newInstance(new Object[]{});
}
}

View File

@ -0,0 +1,96 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
import org.apache.axis.types.URI.MalformedURIException;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNodeManager;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STATUS;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
/**
*
* Trivial default Broker that assigns the target gHNs to services with a round robin policy
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class InternalBroker implements Broker {
private final GCUBELog logger=new GCUBELog(this);
private GCUBEScope scope;
private String[] suggestedGHNs = new String[0];
//used to apply a round robin assignment of the input GHNs (if any)
private int nodewalker = 0;
public InternalBroker() {}
/**
* {@inheritDoc}
*/
public void initialize(GCUBEScope scope) throws Exception {this.scope = scope;}
/**
* {@inheritDoc}
*/
public void makePlan(Session session, Set<ScopedDeployedService> services, String[] suggestedGHNs) throws Exception {
this.suggestedGHNs = suggestedGHNs;
for (ScopedDeployedService service : services) {
try {
this.assignTargetGHN(service);
} catch (NoGHNFoundException e1) {
logger.error(service.getSourceService() + "Unable to find a suitable target gHN");
service.setStatus(STATUS.LOST);
service.setErrorMessage("Unable to find a suitable target gHN");
throw new IOException(service.getSourceService() + " - unable to find a suitable target gHN for this service");
}
}
}
/** Selects a target node for the deployment
*
* @param service the service to deploy
* @throws MalformedURIException
* @throws NoGHNFoundException if the gHN is not found
*/
private void assignTargetGHN(ScopedDeployedService service) throws org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException {
if ( (service.getSourceService().getGHN() != null) && (service.getSourceService().getGHN().compareToIgnoreCase("") != 0)) {
//a specific GHN has been requested
logger.info("A specific GHN (" + service.getSourceService().getGHN() + ") has been requested by the caller for " + service);
VirtualNode node = VirtualNodeManager.getNode(service.getSourceService().getGHN(),this.scope);
node.setWorkingScope(this.scope);
node.isNotWorking();
service.setTargetGHN(node);
} else if (this.suggestedGHNs.length > 0) {
//a set of target GHNs has been requested, assign one of them with a round robin
logger.info("A set of target GHNs " + Arrays.toString(this.suggestedGHNs)+" has been requested by the caller for " + service);
VirtualNode node = VirtualNodeManager.getNode(this.suggestedGHNs[this.nodewalker++ % this.suggestedGHNs.length],this.scope);
node.setWorkingScope(this.scope);
node.isNotWorking();
service.setTargetGHN(node);
} else {
logger.info("no GHN has been specified as explicit target");
//no GHN has been specified as explicit target
throw new NoGHNFoundException("No GHN was assigned to the service from the caller");
}
}
/**
* {@inheritDoc}
*/
public void sendFeedback(Session session) throws Exception {
/* feedback is not managed by this broker*/
}
}

View File

@ -0,0 +1,117 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage;
import java.util.List;
import java.util.Set;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.gcube.common.core.contexts.GCUBERemotePortTypeContext;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.queries.GCUBERIQuery;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcebroker.stubs.ResourceBrokerPortType;
import org.gcube.vremanagement.resourcebroker.stubs.service.ResourceBrokerServiceAddressingLocator;
import org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.Feedback;
import org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.PlanParser;
import org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.PlanRequest;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
/**
*
* Broker that exploits the gCube Resource Broker service
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class ServiceBroker implements Broker {
protected final GCUBELog logger = new GCUBELog(this);
private GCUBEScope scope;
private List<GCUBERunningInstance> instances = null;
private static final int TIMEOUT = 600000; //in milliseconds
public ServiceBroker() {}
/**
* {@inheritDoc}
*/
public void initialize(GCUBEScope scope) throws Exception {
this.scope = scope;
logger.info("Initializing the ServiceBroker..");
this.instances = this.queryForBrokerInstances();
if (this.instances.size() == 0)
throw new Exception("unable to find an instance of the Resource Broker in scope");
logger.info("Broker instances found: #" + this.instances.size());
}
public void makePlan(Session session, Set<ScopedDeployedService> services, String[] suggestedGHNs) throws Exception {
String request = PlanRequest.create(services, suggestedGHNs, scope);;
logger.debug("Request for the Broker \n" + request);
String plan = null;
for (GCUBERunningInstance instance : this.instances) {
EndpointReferenceType endpoint = instance.getAccessPoint().getEndpoint("gcube/vremanagement/ResourceBroker");
logger.debug("Querying broker instance at " + endpoint.getAddress());
try {
plan = this.getBrokerPT(endpoint).getPlan(request);
logger.debug("Plan received from the broker \n" + plan);
break;
} catch (Exception e) {
logger.error("Unable to contact the Resource Broker instance located at " + endpoint.getAddress(), e);
continue;
}
}
PlanParser.parse(plan, services, scope);
session.setDeploymentPlan(plan);
}
/**
* {@inheritDoc}
*/
public void sendFeedback(Session session) throws Exception {
String feedback = Feedback.create(session);
logger.debug("Feedback for the Broker \n" + feedback);
for (GCUBERunningInstance instance : this.instances) {
EndpointReferenceType endpoint = instance.getAccessPoint().getEndpoint("gcube/vremanagement/ResourceBroker");
logger.debug("Sending broker feeback to " + endpoint.getAddress());
try {
this.getBrokerPT(endpoint).handleFeedback(feedback);
break;
} catch (Exception e) {
logger.error("Unable to contact the Resource Broker instance located at " + endpoint.getAddress(), e);
continue;
}
}
}
/**
* Looks for all the Resource Broker instances in Scope
* @return the list of RIs found
* @throws Exception if the query to the IS fails
*/
private List<GCUBERunningInstance> queryForBrokerInstances() throws Exception {
//looks for all the Broker instances
ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBERIQuery lookupQuery = client.getQuery(GCUBERIQuery.class);
lookupQuery.addAtomicConditions(new AtomicCondition("//ServiceName","ResourceBroker"));
lookupQuery.addAtomicConditions(new AtomicCondition("//ServiceClass","VREManagement"));
return client.execute(lookupQuery, this.scope);
}
private ResourceBrokerPortType getBrokerPT(EndpointReferenceType endpoint) throws Exception {
ResourceBrokerPortType pt = new ResourceBrokerServiceAddressingLocator().getResourceBrokerPortTypePort(endpoint);
pt = GCUBERemotePortTypeContext.getProxy(pt, this.scope, TIMEOUT, ServiceContext.getContext());
return pt;
}
}

View File

@ -0,0 +1,63 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker;
import java.io.IOException;
import java.util.Set;
import org.gcube.vremanagement.resourcebroker.utils.serialization.parser.xstream.XStreamTransformer;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PackageGroup;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PlanResponse;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.feedback.DeployNode;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.feedback.FeedbackStatus;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
/**
*
* Feedback for deployment plans. It uses the serialization API provided by the Broker Service
* to create the feedback information.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class Feedback {
/**
* Creates the feedback information for the Broker Service
* @param session the current session
* @return the XML representation of the feedback information
*/
@SuppressWarnings("deprecation")
public static String create(Session session) throws IOException {
Set<ScopedDeployedService> services = session.getServices();
XStreamTransformer transformer = new XStreamTransformer();
PlanResponse resp = transformer.getResponseFromXML(session.getDeploymentPlan(), false);
org.gcube.vremanagement.resourcebroker.utils.serialization.types.feedback.Feedback fb =
new org.gcube.vremanagement.resourcebroker.utils.serialization.types.feedback.Feedback();
fb.setPlanID(resp.getKey());
fb.setScope(resp.getScope());
for (PackageGroup group : resp.getPackageGroups()) {
ScopedDeployedService service = null;
for (ScopedDeployedService s : services) {
if (s.getId().compareToIgnoreCase(group.getServiceName()) == 0) {
service = s;
break;
}
}
//set the status of each package elemnt
for (org.gcube.vremanagement.resourcebroker.utils.serialization.types.PackageElem p : group.getPackages()) {
if (service == null)
p.setStatus(FeedbackStatus.FAILED);
else if (service.isSuccess())
p.setStatus(FeedbackStatus.SUCCESS);
else //this has to be improved by using the PARTIAL state?
p.setStatus(FeedbackStatus.FAILED);
}
DeployNode pgToAdd = new DeployNode(group);
fb.addDeployNode(pgToAdd);
}
return transformer.toXML(fb);
}
}

View File

@ -0,0 +1,71 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker;
import java.io.IOException;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcebroker.utils.serialization.parser.xstream.XStreamTransformer;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PackageGroup;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PlanResponse;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNodeManager;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
/**
*
* Parser for deployment plans. It uses the Serialization API provided by the Broker Service
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class PlanParser {
private static final GCUBELog logger = new GCUBELog(PlanParser.class);
/**
* Parses the current plan and assigns gHNs to services
* @param plan the plan returned by the Broker
* @param services the services to deploy
* @param scope the current scope
* @throws IOException
*/
public static void parse(String plan, Set<ScopedDeployedService> services, GCUBEScope scope) throws IOException {
XStreamTransformer transformer = new XStreamTransformer();
PlanResponse resp = transformer.getResponseFromXML(plan, false);
if (resp.getStatus().getStatus().compareToIgnoreCase("FAILED")==0) {
logger.error("The creation of the Deployment Plan failed. Broker says: " + resp.getStatus().getMsg());
throw new IOException ("Broker says: " + resp.getStatus().getMsg());
} else if (resp.getStatus().getStatus().compareToIgnoreCase("SUCCESS")==0) {
logger.info("The creation of the Deployment Plan was successful");
}
//assing ghns to services
for (PackageGroup group: resp.getPackageGroups()) {
String serviceID = group.getServiceName();
String ghnID = group.getGHN();
if (ghnID == null) {
logger.error("no gHN was assigned to service " + serviceID);
throw new IOException("no gHN was assigned to service " + serviceID);
}
for (ScopedDeployedService service : services) {
if (service.getId().compareToIgnoreCase(serviceID) == 0) {
logger.info("Assigning gHN " + ghnID + " to " +service);
VirtualNode node = null;
try {
node = VirtualNodeManager.getNode(ghnID,scope);
} catch (NoGHNFoundException e) {
logger.error("unable to find gHN " + ghnID + " returned by the Broker");
throw new IOException("unable to find gHN " + ghnID + " returned by the Broker");
}
node.setWorkingScope(scope);
node.isNotWorking();
service.setTargetGHN(node);
break;
}
}
}
}
}

View File

@ -0,0 +1,51 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker;
import java.io.IOException;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Dependency;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcebroker.utils.serialization.parser.xstream.XStreamTransformer;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PackageElem;
import org.gcube.vremanagement.resourcebroker.utils.serialization.types.PackageGroup;
/**
*
* Creates a plan request with the Serialization API provided by the Broker Service
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class PlanRequest {
/**
* Creates the request plan for the Broker Service
* @param services the services to deploy
* @param suggestedGHNs the GHNs suggested for the deployment
* @param scope the scope of the request
* @thrown {@link IOException} if the request cannot be created
* @return the XML representation of the request
*
*/
public static String create(Set<ScopedDeployedService> services, String[] suggestedGHNs, GCUBEScope scope) throws IOException {
org.gcube.vremanagement.resourcebroker.utils.serialization.types.PlanRequest planReq = new org.gcube.vremanagement.resourcebroker.utils.serialization.types.PlanRequest(scope.toString());
for (ScopedDeployedService service : services) {
PackageGroup group = planReq.createPackageGroup( service.getId());
for (Dependency dep : service.getLastResolvedDependencies()) {
group.addPackage(new PackageElem(false, dep.getService().getClazz(), dep.getService().getName(),
dep.getService().getVersion(), dep.getName(), dep.getVersion()));
if (service.getSourceService().getGHN() != null)
group.setGHN(service.getSourceService().getGHN());
}
}
if (suggestedGHNs != null) {
for (String ghn : suggestedGHNs)
planReq.getGHNList().addGHN(ghn);
}
XStreamTransformer transformer = new XStreamTransformer();
return transformer.toXML(planReq);
}
}

View File

@ -0,0 +1,80 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.kxml;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;
import java.util.Set;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.deployment.DeployerReport;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
import org.kxml2.io.KXmlParser;
import org.kxml2.io.KXmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
/**
*
* Feedback for deployment plans. It uses the KXML library to create the feedback information.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class KFeedback {
protected static final GCUBELog logger = new GCUBELog(KFeedback.class);
/**
* Creates the feedback information for the Broker Service
* @param session the current session
* @return the XML representation of the feedback information
* @throws IOException if the feedback information cannot be created
*/
public static String create(Session session) throws IOException {
Map<String, DeployerReport> reports = session.getAllGHNReports();
Set<ScopedDeployedService> services = session.getServices();
KXmlParser parser = new KXmlParser();
try {
parser.setInput(new BufferedReader(new StringReader(session.getDeploymentPlan())));
} catch (XmlPullParserException e) {
logger.error("Unable to parse the Deployment Plan", e);
throw new IOException ("Unable to parse the Deployment Plan");
}
StringWriter feedbackRequest = new StringWriter();
KXmlSerializer serializer = new KXmlSerializer();
serializer.setOutput(feedbackRequest);
serializer.startDocument("UTF-8", true);
serializer.setPrefix("", "http://gcube-system.org/namespaces/resourcebroker/broker/xsd/deployFeedback");
serializer.startTag(null,"KFeedback").attribute(null, "planID", getPlanID(parser));;
serializer.startTag(null,"Scope").text(session.getScope().toString()).endTag(null,"Scope");
for (String ghnid : reports.keySet()) {
serializer.startTag(null,"DeployNode");
//TODO: to complete
serializer.startTag(null,"GHN").text(ghnid).endTag(null, "GHN");
serializer.endTag(null,"DeployNode");
}
serializer.endTag(null,"KFeedback");
return feedbackRequest.toString();
}
private static String getPlanID(KXmlParser parser) throws IOException {
String id = "";
loop: while (true) {
try {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("PlanResponse")) id = parser.getAttributeValue(null, "deployID");
break loop;
case KXmlParser.END_DOCUMENT: break loop;
}
} catch (Exception e) {
logger.error("Unable to parse the Deployment Plan", e);
throw new IOException ("The creation of the Deployment Plan failed. " + e.getMessage());
}
}
return id;
}
}

View File

@ -0,0 +1,117 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.kxml;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNodeManager;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParserException;
/**
*
* Parser for deployment plans. It uses the KXML library to parse the plan.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class KPlanParser {
private static final GCUBELog logger = new GCUBELog(KPlanParser.class);
/**
* Parses the current plan and assigns gHNs to services
* @param plan the plan returned by the Broker
* @param services the services to deploy
* @param scope the current scope
* @throws IOException
*/
public static void parse(String plan, Set<ScopedDeployedService> services, GCUBEScope scope) throws IOException {
KXmlParser parser = new KXmlParser();
try {
parser.setInput(new BufferedReader(new StringReader(plan)));
} catch (XmlPullParserException e) {
logger.error("Unable to parse the Deployment Plan", e);
throw new IOException ("Unable to parse the Deployment Plan");
}
loop: while (true) {
try {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("Status")) parseStatus(parser);
else if (parser.getName().equals("PackageGroup")) parsePackageGroup(services, parser, scope);
break;
case KXmlParser.END_DOCUMENT: break loop;
}
} catch (Exception e) {
logger.error("Unable to parse the Deployment Plan", e);
throw new IOException ("The creation of the Deployment Plan failed. " + e.getMessage());
}
}
}
private static void parseStatus(KXmlParser parser) throws IOException {
String value = parser.getAttributeValue(null, "value");
String errorMsg = "";
if (value.compareToIgnoreCase("FAILED")==0) {
loop: while (true) {
try {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("ErrorMsg")) errorMsg = parser.nextText();
break;
case KXmlParser.END_TAG: if (parser.getName().equals("Status")) break loop;
}
} catch (Exception e) {
logger.error("Unable to parse the Deployment Plan at Status element", e);
throw new IOException ("Failed to parse at Status element");
}
}
logger.error("The creation of the Deployment Plan failed. Broker says: " + errorMsg);
throw new IOException ("Broker says: " + errorMsg);
} else if (value.compareToIgnoreCase("SUCCESS")==0) {
logger.info("The creation of the Deployment Plan was successful");
}
}
private static void parsePackageGroup(Set<ScopedDeployedService> services, KXmlParser parser, GCUBEScope scope) throws IOException, NoGHNFoundException {
String serviceID = parser.getAttributeValue(null, "service");
String ghnID = null;
loop: while (true) {
try {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("GHN")) ghnID = parser.nextText();
break;
case KXmlParser.END_TAG: if (parser.getName().equals("PackageGroup")) break loop;
}
} catch (Exception e) {
logger.error("Unable to parse the Deployment Plan at PackageGroup element", e);
throw new IOException ("Failed to parse at PackageGroup element");
}
}
if (ghnID == null) {
logger.error("a gHN was not assigned to service " + serviceID);
throw new NoGHNFoundException("a gHN was not assigned to service " + serviceID);
}
for (ScopedDeployedService service : services) {
if (service.getId().compareToIgnoreCase(serviceID) == 0) {
logger.info("Assigning gHN " + ghnID + " to " +service);
VirtualNode node = VirtualNodeManager.getNode(ghnID,scope);
node.setWorkingScope(scope);
service.setTargetGHN(node);
break;
}
}
}
}

View File

@ -0,0 +1,110 @@
package org.gcube.vremanagement.resourcemanager.impl.brokerage.servicebroker.kxml;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Dependency;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.kxml2.io.KXmlSerializer;
/**
*
* Creates a plan request with the KXML library to create the deployment plan request.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class KPlanRequest {
/**
* Creates the request plan for the Broker Service
*
* @param services
* the services to deploy
* @param suggestedGHNs
* the GHNs suggested for the deployment
* @param scope
* the scope of the request
* @thrown {@link IOException} if the request cannot be created
* @return the XML representation of the request
*
*/
public static String create(Set<ScopedDeployedService> services,
String[] suggestedGHNs, GCUBEScope scope) throws IOException {
StringWriter request = new StringWriter();
KXmlSerializer serializer = new KXmlSerializer();
serializer.setOutput(request);
serializer.startDocument("UTF-8", true);
serializer.setPrefix("","http://gcube-system.org/namespaces/resourcebroker/broker/xsd/deployRequest");
serializer.startTag(null, "PlanRequest");
serializer.startTag(null, "Scope").text(scope.toString()).endTag(null,"Scope");
// for each service, prepare a section like this:
// <PackageGroup service="service1">
// <Package reuse="true">
// <ServiceClass>PkgServiceClass</ServiceClass>
// <ServiceName>PkgServiceName</ServiceName>
// <ServiceVersion>PkgServiceVersion</ServiceVersion>
// <PackageName>PkgPackageName</PackageName>
// <PackageVersion>PkgPackageVersion</PackageVersion>
// </Package>
// <Package reuse="true">
// <ServiceClass>PkgServiceClass2</ServiceClass>
// <ServiceName>PkgServiceName2</ServiceName>
// <ServiceVersion>PkgServiceVersion2</ServiceVersion>
// <PackageName>PkgPackageName2</PackageName>
// <PackageVersion>PkgPackageVersion2</PackageVersion>
// </Package>
// <GHN>d5a5af20-ac50-11de-a928-ab32081f9f00</GHN>
// </PackageGroup>
for (ScopedDeployedService service : services) {
serializer.startTag(null, "PackageGroup").attribute(null,
"service", service.getId());
for (Dependency dep : service.getLastResolvedDependencies()) {
serializer.startTag(null, "Package").attribute(null, "reuse",
"false");
serializer.startTag(null, "ServiceClass").text(
dep.getService().getClazz()).endTag(null,
"ServiceClass");
serializer.startTag(null, "ServiceName").text(
dep.getService().getName()).endTag(null, "ServiceName");
serializer.startTag(null, "ServiceVersion").text(
dep.getService().getVersion()).endTag(null,
"ServiceVersion");
serializer.startTag(null, "PackageName").text(dep.getName())
.endTag(null, "PackageName");
serializer.startTag(null, "PackageVersion").text(
dep.getVersion()).endTag(null, "PackageVersion");
serializer.endTag(null, "Package");
}
if (service.getSourceService().getGHN() != null)
serializer.startTag(null, "GHN").text(service.getSourceService().getGHN()).endTag(null, "GHN");
serializer.endTag(null, "PackageGroup");
}
// GHNLIST
if (suggestedGHNs != null) {
serializer.startTag(null, "GHNList");
for (String ghn : suggestedGHNs)
serializer.startTag(null, "GHN").text(ghn).endTag(null, "GHN");
serializer.endTag(null, "GHNList");
}
serializer.endTag(null, "PlanRequest");
return request.toString();
}
public static void main(String[] args) {
try {
System.out.println(create(new HashSet<ScopedDeployedService>(),
new String[] { "ID" }, GCUBEScope.getScope("/gcube")));
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,116 @@
package org.gcube.vremanagement.resourcemanager.impl.contexts;
import java.io.File;
import org.gcube.common.core.contexts.GCUBEServiceContext;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.handlers.GCUBEHandler;
import org.gcube.common.core.utils.handlers.GCUBEScheduledHandler;
import org.gcube.vremanagement.resourcemanager.impl.ResourceManager;
/**
* ResourceManager service context implementation
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class ServiceContext extends GCUBEServiceContext {
static ServiceContext cache = new ServiceContext();
/**
* Gets the current service context
* @return the service context
*/
public static ServiceContext getContext() {
return cache;
}
@Override protected String getJNDIName() {
return "gcube/vremanagement/ResourceManager/service";
}
/**
* {@inheritDoc}
*
*/
@SuppressWarnings("unchecked")
protected void onReady() throws Exception {
super.onReady();
// no more than one scope is allowed!
if (ServiceContext.getContext().getInstance().getScopes().values().size() != 1) {
logger.fatal("ResourceManager is misconfigured, cannot start the service in multiple scopes");
throw new IllegalServiceScopeException("ResourceManager has been configured to join more than one scope, while it can work only in ONE single scope");
}
//creates the stateful resource for the service with a short delay
HStateScheduler stateScheduler = new HStateScheduler(10, GCUBEScheduledHandler.Mode.LAZY);
stateScheduler.setScheduled(new HState());
stateScheduler.run();
}
/**
* Creates/updates the Deployer stateful resource
*
* @author Manuele Simi (ISTI-CNR)
*
*/
@SuppressWarnings("unchecked")
protected class HStateScheduler extends GCUBEScheduledHandler {
public HStateScheduler(long interval, Mode mode) {
super(interval, mode);
}
@Override
protected boolean repeat(Exception exception, int exceptionCount) {
if (exception!=null) {
logger.warn("Failed to create the vre manager resource (attempt "+exceptionCount+" out of 20)",exception);
if (exceptionCount >= 20) {
logger.error("Max attempts reached, no more chance to register the ResourceManager resource, the service startup failed");
ServiceContext.getContext().setStatus(GCUBEServiceContext.Status.FAILED);
return false;
} else
return true;
} else {
return false;
}
}
}
/** Tries to create the resource in all the instance scopes*/
protected class HState extends GCUBEHandler<Object> {
public HState() {}
public void run() throws Exception {
GCUBEScope scope = ServiceContext.getContext().getInstance().getScopes().values().iterator().next();
logger.trace("Adding ResourceManager resource to " + scope);
ServiceContext.getContext().setScope(scope);
StatefulPortTypeContext.getContext().getWSHome().create(StatefulPortTypeContext.getContext().makeKey(ResourceManager.SINGLETON_RESOURCE_KEY));
}
}
/**
* Given a relative path in the /etc folder of the service, returns its absolute path
*
* @param path a relative path to a configuration file or folder
* @return the absolute path of the file
*/
public String getConfigurationFileAbsolutePath(String relativepath) {
File file = super.getFile(relativepath, false);
//eventually creates the directory tree if needed
if (!file.exists() || file.isDirectory()) {file.mkdirs();}
return file.getAbsolutePath();
}
/** IllegalServiceScopeException exception */
public static class IllegalServiceScopeException extends Exception{
private static final long serialVersionUID = 1L;
public IllegalServiceScopeException(String message) {super(message);}};
}

View File

@ -0,0 +1,40 @@
package org.gcube.vremanagement.resourcemanager.impl.contexts;
import org.gcube.common.core.contexts.GCUBEServiceContext;
import org.gcube.common.core.contexts.GCUBEStatefulPortTypeContext;
/**
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class StatefulPortTypeContext extends GCUBEStatefulPortTypeContext {
static StatefulPortTypeContext cache = new StatefulPortTypeContext();
@Override
public String getJNDIName() {
return "gcube/vremanagement/ResourceManager";
}
@Override
public String getNamespace() {
return "http://gcube-system.org/namespaces/vremanagement/vremanager";
}
@Override
public GCUBEServiceContext getServiceContext() {
return ServiceContext.getContext();
}
/**
*
* @return the stateful context
*/
public static GCUBEStatefulPortTypeContext getContext() {
return cache;
}
}

View File

@ -0,0 +1,383 @@
package org.gcube.vremanagement.resourcemanager.impl.deployment;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.DeployedDependency;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Service;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedRunningInstance;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STATUS;
import org.gcube.vremanagement.resourcemanager.impl.state.ProfileDate;
import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParserException;
/**
* Parser for the report sent by the Deployer Service
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class DeployerReport {
protected GCUBELog logger = new GCUBELog(this);
private String report = "";
private String status = "";
private String id = "";
private String host = "";
private String type = "";
private Date lastUpdate;
private List<DeployedDependency> dependencies = new ArrayList<DeployedDependency>();
private Set<DeployedRunningInstance> instances = new HashSet<DeployedRunningInstance>();
/**
*
* @param report the string representation of the report as sent by a Deployer Service
*
*/
public DeployerReport(String report) throws Exception {
this.report = report;
try {
this.parse();
} catch (XmlPullParserException e) {
throw new Exception("invalid Deployer Report");
}
}
/**
* Gets the GHN ID
* @return the id
*
* @throws Exception if it is impossible to parse the Deployer Report or the GHNID element is not found
*/
public String getGHNID() {
//look for GHNID element
return this.id;
}
public String toString() {
return this.report;
}
/**
* @return the type
*/
public String getType() {
return type;
}
/**
* @return the lastUpdate
*/
public Date getLastUpdate() {
return lastUpdate;
}
/**
* @return the dependencies
*/
public List<DeployedDependency> getDependencies() {
return dependencies;
}
/**
*
* @return the hostname from which the report was sent
*/
public String getHost() {
return this.host;
}
private void parse() throws Exception {
KXmlParser parser = new KXmlParser();
parser.setInput(new BufferedReader(new StringReader(report)));
loop: while (true) {
try {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("GHNID")) this.id = parser.nextText();
else if (parser.getName().equals("Type")) this.type = parser.nextText();
else if (parser.getName().equals("LastUpdate")) this.lastUpdate = ProfileDate.fromXMLDateAndTime( parser.nextText());
else if (parser.getName().equals("Status")) this.status = parser.nextText();
else if (parser.getName().equals("Packages")) this.parsePackages(parser);
else if (parser.getName().equals("NewInstances")) this.parseInstances(parser);
break;
case KXmlParser.END_DOCUMENT: break loop;
}
} catch (Exception e) {
logger.error("Unable to parse the Deployer Report",e);
throw new Exception ("Unable to parse the Deployer Report",e);
}
}
}
private void parseInstances(KXmlParser parser) throws Exception {
loop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("NewInstance")) {
DeployedRunningInstance instance = new DeployedRunningInstance();
innerloop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("ID")) instance.setRIId(parser.nextText());
if (parser.getName().equals("ServiceClass")) instance.setServiceClass(parser.nextText());
if (parser.getName().equals("ServiceName")) instance.setServiceName(parser.nextText());
if (parser.getName().equals("ServiceVersion")) instance.setServiceVersion(parser.nextText());
if (parser.getName().equals("PackageVersion")) instance.setPackageVersion(parser.nextText());
if (parser.getName().equals("PackageName")) instance.setPackageName(parser.nextText());
break ;
case KXmlParser.END_TAG: if (parser.getName().equals("NewInstance")){
try {
ScopedRunningInstance ri = (ScopedRunningInstance) ScopedResourceFactory.newResource(instance.getRIID(), GCUBERunningInstance.TYPE, ServiceContext.getContext().getScope());
ri.setHostedON(this.host);
ri.setJointTime(Calendar.getInstance().getTime());
ri.setStatus(STATUS.PUBLISHED);
instance.setInstance(ri);
instance.isAlive = true;
instance.setMessage("An instance of this service has been correctly activated on " + this.host);
} catch (Exception e) {
logger.error("An instance of this service has been activated but it didn't start correctly on " + this.host + ". The expected instance identifier was " + instance.getRIID(), e);
instance.setMessage("An instance of this service has been activated but it didn't start correctly on " + this.host + ". The expected instance identifier was " + instance.getRIID());
instance.isAlive = false;
} finally {
this.instances.add(instance);
}
break innerloop;
}
break;
case KXmlParser.END_DOCUMENT: throw new Exception ("Parsing failed at NewInstance");
}
}
}
break;
case KXmlParser.END_TAG: if (parser.getName().equals("NewInstances")) break loop;
break;
case KXmlParser.END_DOCUMENT: throw new Exception ("Parsing failed at NewInstances");
}
}
}
private void parsePackages(KXmlParser parser) throws Exception {
loop: while (true) {
try {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("Package")) {
DeployedDependency dd = new DeployedDependency();
dd.setService(new Service());
innerloop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("ServiceClass")) {dd.getService().setClazz(parser.nextText());}
else if (parser.getName().equals("ServiceName")) {dd.getService().setName(parser.nextText());}
else if (parser.getName().equals("ServiceVersion")) {dd.getService().setVersion(parser.nextText());}
else if (parser.getName().equals("PackageName")) {dd.setName(parser.nextText());}
else if (parser.getName().equals("PackageVersion")) {dd.setVersion(parser.nextText());}
else if (parser.getName().equals("Status")) {dd.setStatus(parser.nextText());}
else if (parser.getName().equals("Host")) {dd.setHost(parser.nextText()); this.host = dd.getHost();}
else if (parser.getName().equals("Message")) {dd.setMessage(parser.nextText());}
else parser.nextText();
break;
case KXmlParser.END_TAG: if (parser.getName().equals("Package")){ this.dependencies.add(dd); break innerloop;}
break;
case KXmlParser.END_DOCUMENT: throw new Exception ("Parsing failed at Package");
}
}
}
break;
case KXmlParser.END_TAG: if (parser.getName().equals("Packages")) break loop;
break;
case KXmlParser.END_DOCUMENT: throw new Exception ("Parsing failed at Packages");
}
} catch (Exception e) {
throw new Exception ("Unable to parse the Deployer Report");
}
}
}
/**
* @return the status
*/
public String getStatus() {
return this.status;
}
/**
* @return the instances
*/
public Set<DeployedRunningInstance> getInstances() {
return this.instances;
}
public final class DeployedRunningInstance {
private ScopedRunningInstance instance;
private String riid;
private String serviceClass;
private String serviceName;
private String serviceVersion;
private String packageName;
private String packageVersion;
private boolean isAlive;
private String message;
/**
* @return the instance
*/
public ScopedRunningInstance getInstance() {
return instance;
}
/**
* @param instance the instance to set
*/
public void setInstance(ScopedRunningInstance instance) {
this.instance = instance;
}
/**
* @return the serviceClass
*/
public String getServiceClass() {
return serviceClass;
}
/**
* @param serviceClass the serviceClass to set
*/
public void setServiceClass(String serviceClass) {
this.serviceClass = serviceClass;
}
/**
* @return the serviceName
*/
public String getServiceName() {
return serviceName;
}
/**
* @param serviceName the serviceName to set
*/
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
/**
* @return the serviceVersion
*/
public String getServiceVersion() {
return serviceVersion;
}
/**
* @param serviceVersion the serviceVersion to set
*/
public void setServiceVersion(String serviceVersion) {
this.serviceVersion = serviceVersion;
}
/**
* @return the packageName
*/
public String getPackageName() {
return packageName;
}
/**
* @param packageName the packageName to set
*/
public void setPackageName(String packageName) {
this.packageName = packageName;
}
/**
* @return the packageVersion
*/
public String getPackageVersion() {
return packageVersion;
}
/**
* @param packageVersion the packageVersion to set
*/
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
/**
* @return the riid
*/
public String getRIID() {
return riid;
}
/**
* @param riid the riid to set
*/
public void setRIId(String riid) {
this.riid = riid;
}
/**
* @return the isAlive
*/
public boolean isAlive() {
return isAlive;
}
/**
* @param isAlive the isAlive to set
*/
public void setAlive(boolean isAlive) {
this.isAlive = isAlive;
}
/**
* @return the message
*/
public String getMessage() {
return message;
}
/**
* @param message the message to set
*/
public void setMessage(String message) {
this.message = message;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((riid == null) ? 0 : riid.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DeployedRunningInstance other = (DeployedRunningInstance) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (riid == null) {
if (other.riid != null)
return false;
} else if (!riid.equals(other.riid))
return false;
return true;
}
private DeployerReport getOuterType() {
return DeployerReport.this;
}
}
}

View File

@ -0,0 +1,261 @@
package org.gcube.vremanagement.resourcemanager.impl.deployment;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.gcube.common.core.contexts.GCUBERemotePortTypeContext;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.queries.GCUBERIQuery;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Dependency;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Service;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.softwaregateway.stubs.AccessPortType;
import org.gcube.vremanagement.softwaregateway.stubs.DependenciesCoordinates;
import org.gcube.vremanagement.softwaregateway.stubs.service.AccessServiceAddressingLocator;
import org.kxml2.io.KXmlParser;
/**
* Request for the Software Repository service to solve the service2package
* relationships
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class SoftwareGatewayRequest {
private Map<ScopedDeployedService, DependenciesCoordinates> requests = new HashMap<ScopedDeployedService, DependenciesCoordinates>();
protected static final String RESOLVED_DEPS_KEY = "listResolvedDeps";
protected static final String MISSING_DEPS_KEY = "listMissingDeps";
/** Target port-type name. */
protected static final String REPOSITORY_ENDPOINT = "gcube/vremanagement/softwaregateway/Access";
/** Target service name. */
protected static final String REPOSITORY_NAME = "SoftwareGateway";
/** Target service class. */
protected static final String REPOSITORY_CLASS = "VREManagement";
/** Timeout for contacting the target service. */
protected static final int TIMEOUT = 600000; //in milliseconds
/** Object logger */
protected final GCUBELog logger = new GCUBELog(this);
/**
* Adds a new service to the request
*
* @param service
*/
public void addService(ScopedDeployedService service) {
DependenciesCoordinates message = new DependenciesCoordinates();
message.setServiceClass(service.getSourceService().getClazz());
message.setServiceName(service.getSourceService().getName());
message.setServiceVersion(service.getSourceService().getVersion());
requests.put(service, message);
}
/**
* Sends the request to the appropriate SR
*
* @throws Exception
*/
public List<ScopedDeployedService> send() throws Exception {
List<ScopedDeployedService> service2package = new ArrayList<ScopedDeployedService>();
Map<GCUBEScope, Set<EndpointReferenceType>> eprs = this.findInstances();
for (ScopedDeployedService service : requests.keySet()) {
DependenciesCoordinates packageCoordinates = requests.get(service);
logger.trace("Checking deps for " + packageCoordinates.getServiceName());
//look for service deps in one of the instances found
inner: for (GCUBEScope scope : eprs.keySet()) {
for (EndpointReferenceType epr : eprs.get(scope)) {
try {
logger.trace("Trying Service Repository located at "+ epr);
AccessServiceAddressingLocator locator = new AccessServiceAddressingLocator();
AccessPortType pt = locator.getAccessPortTypePort(epr);
String report = GCUBERemotePortTypeContext.getProxy(pt, scope, TIMEOUT, ServiceContext.getContext()).getDependencies(packageCoordinates);
service2package.add(parseDependenciesReport(service, report));
break inner;//no need for looping on the other instances, we just need that one satisfies the request
} catch (Exception e) {
logger.warn("Unable to check deps for " + packageCoordinates.getServiceName() + " from Service Repository in " + scope + ": "+ e.getMessage(), e);
}
}
// if we are here, no SR instance was able to resolve the dependencies
//ResolvedService s = new ResolvedService(service);
service.setErrorMessage("Unable to check deps for this service in any of the Service Repository instance in scope");
service2package.add(service);
}
}
return service2package;
}
/**
* Parses the dependencies report
* @param report
* @return
*/
private ScopedDeployedService parseDependenciesReport(ScopedDeployedService service, String report) throws Exception {
//ResolvedService depsMap = new ResolvedService(service);
KXmlParser parser = new KXmlParser();
parser.setInput(new BufferedReader(new StringReader(report)));
logger.trace("Parsing: " + report);
try {
loop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("ResolvedDependencies")) this.parseResolvedDependencies(parser, service);
if (parser.getName().equals("MissingDependencies")) this.parseMissingDependencies(parser, service);
break;
case KXmlParser.END_DOCUMENT:
break loop;
}
}
} catch (Exception e) {
logger.error("Unable to parse the deployment report returned by the Software Repository", e);
}
return service;
}
/**
* Parses the service section of a dependency
*
* @param parser the XML parser
* @param s the service to populate
* @throws Exception
*/
private void parseService(KXmlParser parser, Service s) throws Exception {
inloop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("Class"))
s.setClazz(parser.nextText());
if (parser.getName().equals("Name"))
s.setName(parser.nextText());
if (parser.getName().equals("Version"))
s.setVersion(parser.nextText());
break;
case KXmlParser.END_TAG:
if (parser.getName().equals("Service"))
break inloop;
break;
case KXmlParser.END_DOCUMENT:
throw new Exception("Parsing failed at Service");
}
}
}
/**
* Parses a generic dependency section (both missing and resolved)
*
* @param parser the XML parser
* @return the dependency
* @throws Exception
*/
private Dependency parseDependency(KXmlParser parser) throws Exception {
Dependency p = new Dependency();
loop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("Service")) parseService(parser, p.getService());
if (parser.getName().equals("Package")) p.setName(parser.nextText());
if (parser.getName().equals("Version")) p.setVersion(parser.nextText());
break;
case KXmlParser.END_TAG:
if ((parser.getName().equals("Dependency")) || (parser.getName().equals("MissingDependency"))) break loop;
break;
case KXmlParser.END_DOCUMENT:
throw new Exception("Parsing failed at Dependency");
}
}
return p;
}
private void parseResolvedDependencies(KXmlParser parser, ScopedDeployedService service) throws Exception {
logger.trace("Parsing resolved dependencies...");
List<Dependency> resolved = new ArrayList<Dependency>();
loop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("Dependency")) {
logger.trace("Dependency found");
resolved.add(this.parseDependency(parser));
} break;
case KXmlParser.END_TAG:
if (parser.getName().equals("ResolvedDependencies")) break loop;
break;
case KXmlParser.END_DOCUMENT:
throw new Exception("Parsing failed at ResolvedDependencies");
}
}
logger.trace("Number of deps found: " + resolved.size());
service.setResolvedDependencies(resolved);
}
private void parseMissingDependencies(KXmlParser parser, ScopedDeployedService service) throws Exception {
logger.trace("Parsing missing dependencies...");
List<Dependency> missing = new ArrayList<Dependency>();
loop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("MissingDependency")) {
logger.trace("Dependency found");
missing.add(this.parseDependency(parser));
} break;
case KXmlParser.END_TAG:
if (parser.getName().equals("MissingDependencies")) break loop;
break;
case KXmlParser.END_DOCUMENT:
throw new Exception("Parsing failed at MissingDependencies");
}
}
logger.trace("Number of deps found: " + missing.size());
service.setMissingDependencies(missing);
}
/**
* Finds instances of the Software Repository service in the current scope(s)
* @return the list of scopes and the EPR of the available SR
* @throws Exception
*/
protected Map<GCUBEScope, Set<EndpointReferenceType>> findInstances()throws Exception {
Map<GCUBEScope, Set<EndpointReferenceType>> scopeMap = new HashMap<GCUBEScope, Set<EndpointReferenceType>>();
logger.debug("Looking for SR instances...");
ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBERIQuery lookupQuery = client.getQuery(GCUBERIQuery.class);
lookupQuery.addAtomicConditions(new AtomicCondition("//ServiceName",REPOSITORY_NAME));
lookupQuery.addAtomicConditions(new AtomicCondition("//ServiceClass",REPOSITORY_CLASS));
for (GCUBEScope scope : ServiceContext.getContext().getInstance().getScopes().values()) {
/*
* if (scope.isInfrastructure()) //TODO: deploy only in a PublishedScopeResource
* continue;
*/
logger.debug("Quering in scope " + scope);
List<GCUBERunningInstance> list = client.execute(lookupQuery, scope);
logger.debug("Found N." + list.size() + " instances");
for (GCUBERunningInstance instance : list) {
logger.trace("Found instance " + instance.toString());
EndpointReferenceType epr = instance.getAccessPoint().getEndpoint(REPOSITORY_ENDPOINT);
logger.trace("Found EPR " + epr.toString());
if (!scopeMap.keySet().contains(scope)) {
Set<EndpointReferenceType> l = new HashSet<EndpointReferenceType>();
scopeMap.put(scope, l);
}
scopeMap.get(scope).add(epr);
}
}
return scopeMap;
}
}

View File

@ -0,0 +1,303 @@
package org.gcube.vremanagement.resourcemanager.impl.deployment;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.gcube.common.core.contexts.GCUBERemotePortTypeContext;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGHNQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBERIQuery;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.common.vremanagement.deployer.stubs.common.PackageInfo;
import org.gcube.common.vremanagement.deployer.stubs.deployer.DeployParameters;
import org.gcube.common.vremanagement.deployer.stubs.deployer.DeployerPortType;
import org.gcube.common.vremanagement.deployer.stubs.deployer.UndeployParameters;
import org.gcube.common.vremanagement.deployer.stubs.deployer.service.DeployerServiceAddressingLocator;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.contexts.StatefulPortTypeContext;
/**
* A target node for deployment and undeployment operations
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class VirtualNode {
/** Object logger */
protected final GCUBELog logger=new GCUBELog(this);
/**the callback identifier to send to the Deployer*/
private String callbackID;
private String ghnID = "";
private GCUBEScope scope = null;
private boolean isWorking = false;
private Set<PackageInfo> packagesToAdd = new HashSet<PackageInfo>();
private Set<PackageInfo> packagesToRemove = new HashSet<PackageInfo>();
private long lastActivity;
//here only for backward compatibility (deserialization will fail)
private String name = "";
//if we do not receive a deployment session from the node after one hour, we assume that the node is not working anymore
private static final long MAX_ACTIVITY = 3600 * 1000; //1h in milliseconds
protected VirtualNode(String ID, GCUBEScope scope) throws NoGHNFoundException {
this.ghnID = ID;
this.scope = scope;
}
public void setCallbackID(String id) {
this.callbackID = id;
}
public String detectName() throws NoGHNFoundException {
logger.debug("Detecting name for " + this.ghnID);
if (GHNContext.getContext().getGHNID().compareToIgnoreCase(this.ghnID) == 0)
throw new NoGHNFoundException ("cannot deploy on the same GHN (ghnID=" + this.ghnID + ") where the Resource Manager is deployed");
try {
ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEGHNQuery query = client.getQuery(GCUBEGHNQuery.class);
query.addAtomicConditions(new AtomicCondition("/ID/text()", this.ghnID));
return client.execute(query, this.scope).get(0).getNodeDescription().getName();
} catch (Exception e) {
logger.error("unable to find the target GHN (ghnID=" + this.ghnID + ")", e);
throw new NoGHNFoundException ("unable to find the target GHN (ghnID=" + this.ghnID + ")");
}
}
/**
* Sets the packages to remove in the next {@link #deploy()} invocation
*
* @param packages the list of packagesT to add
*/
public synchronized void setPackagesToAdd(Set<PackageInfo> packages) {
//check if there is a node with all the packagesToAdd already scheduled to be deployed
//if so, the service will be already activated there, therefore there is nothing to do
if (this.hasPackages(packages))
return;
this.packagesToAdd.addAll(packages);
}
/**
* Gets the packagesToAdd available on this node
*
* @return the packagesToAdd
*/
protected Set<PackageInfo> getPackages() {
return this.packagesToAdd;
}
/**
* Checks if a list of packagesToAdd is already on this node
*
* @param packagesToAdd the list of packagesToAdd to check
* @return true if all the packagesToAdd are already on this node, false otherwise
*/
protected boolean hasPackages(Set<PackageInfo> packages) {
if (packages.size() == 0)
return false;
if (this.packagesToAdd.size() == 0)
return false;
input: for (PackageInfo inputPackage : packages) {
for (PackageInfo nodePackage : this.packagesToAdd) {
if ( (inputPackage.getServiceClass().compareToIgnoreCase(nodePackage.getServiceClass())==0) &&
(inputPackage.getServiceName().compareToIgnoreCase(nodePackage.getServiceName())==0) &&
(inputPackage.getServiceVersion().compareToIgnoreCase(nodePackage.getServiceVersion())==0) &&
(inputPackage.getName().compareToIgnoreCase(nodePackage.getName())==0) &&
(inputPackage.getVersion().compareToIgnoreCase(nodePackage.getVersion())==0))
continue input;
}
return false; //if we arrive here, no matching package has been found
}
return true;
}
/**
* Gets the node ghnID
*
* @return the node ghnID
*/
public String getID() {
return this.ghnID;
}
/**
* Sends a request to the physical node to deploy the active list of packages to add
*
* @throws Exception if the deployment fails
*/
public synchronized void deploy(GCUBEScope scope) throws Exception {
if (packagesToAdd.size() == 0)
return;
if (isWorking && ((System.currentTimeMillis() -this.lastActivity) < MAX_ACTIVITY)) {
logger.warn("Can't deploy on " + this +", the gHN is already working");
return;
}
EndpointReferenceType callbackEPR = ServiceContext.getContext().getInstance().getAccessPoint().getEndpoint(StatefulPortTypeContext.getContext().getJNDIName());
DeployParameters param = new DeployParameters();
param.set_package(this.packagesToAdd.toArray(new PackageInfo[0]));
param.setTargetScope(new String[] {scope.toString()});
param.setCallbackID(callbackID);
param.setEndpointReference(callbackEPR);
EndpointReferenceType nodeEPR = this.loadDeployer(this.ghnID);
logger.trace("Deploying on " + nodeEPR.toString());
DeployerPortType pt = GCUBERemotePortTypeContext.getProxy(new DeployerServiceAddressingLocator().getDeployerPortTypePort(nodeEPR),
scope, ServiceContext.getContext());
pt.deploy(param);
this.packagesToAdd.clear();
isWorking = true;//this will prevent further requests to the ghn until the deployment session is received back
this.lastActivity = System.currentTimeMillis();
}
/**
* Undeploys the packages from the node
* @param scope the scope to use for the undeployment
*
* @throws Exception if the operation fails
*/
public synchronized void undeploy(GCUBEScope scope) throws Exception {
if (this.packagesToRemove.size() == 0)
return;
if (isWorking && (this.lastActivity - System.currentTimeMillis() < MAX_ACTIVITY)) {
logger.warn("Can't undeploy from " + this +", the gHN is already working");
return;
}
EndpointReferenceType callbackEPR = ServiceContext.getContext().getInstance().getAccessPoint().getEndpoint(StatefulPortTypeContext.getContext().getJNDIName());
UndeployParameters params = new UndeployParameters();
params.set_package(this.packagesToRemove.toArray(new PackageInfo[0]));
params.setTargetScope(new String[] {scope.toString()});
params.setCallbackID(callbackID);
params.setEndpointReference(callbackEPR);
EndpointReferenceType nodeEPR = this.loadDeployer(this.ghnID);
logger.trace("Undeploying from " + nodeEPR.toString() + " in scope " + scope);
DeployerPortType pt = GCUBERemotePortTypeContext.getProxy(new DeployerServiceAddressingLocator().getDeployerPortTypePort(nodeEPR),
scope, ServiceContext.getContext());
pt.undeploy(params);
this.packagesToRemove.clear();
isWorking = true;//this will prevent further requests to the ghn until the deployment session is received back
this.lastActivity = System.currentTimeMillis();
}
/** NoGHNFoundException exception */
public static class NoGHNFoundException extends Exception {
private static final long serialVersionUID = 1L;
public NoGHNFoundException(String message) {super(message);}
}
/**
* Marks the node as not working node
* (usually called when a closed {@link DeployerReport} is received from the node)
*/
public void isNotWorking() {
this.isWorking = false;
}
/**
* Sets the packages to remove in the nect {@link #undeploy()} invocation
* @param packages the packages to remove from the node
*/
public synchronized void setPackagesToRemove(Set<PackageInfo> packages) {
this.packagesToRemove.addAll(packages);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "VirtualNode [ghnID=" + ghnID + ", scope="+ scope + "]";
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((ghnID == null) ? 0 : ghnID.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
VirtualNode other = (VirtualNode) obj;
if (ghnID == null) {
if (other.ghnID != null)
return false;
} else if (!ghnID.equals(other.ghnID))
return false;
return true;
}
/**
* Assigns a working scope to the node
* @param scope the scope to set
*/
public void setWorkingScope(GCUBEScope scope) {
this.scope = scope;
}
/**
* Gets the packages scheduled for the next deployment on this node
* @return the set of packages
*/
public Set<PackageInfo> getScheduledPackages() {
return this.packagesToAdd;
}
/**
* Gets the current scope used on this node
* @return the current scope
*/
public GCUBEScope getWorkingScope() {
return this.scope;
}
/**
* Looks for the Deployer's endpoint to contact
* @param id the identifier of the gHN
* @return the endpoint reference of Deployer's portType to contact
* @throws Exception if the search fails
*/
private EndpointReferenceType loadDeployer(String id) throws Exception {
ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBERIQuery riquery = client.getQuery(GCUBERIQuery.class);
riquery.addAtomicConditions(new AtomicCondition("//GHN/@UniqueID", id),
new AtomicCondition("//ServiceClass", "VREManagement"),
new AtomicCondition("//ServiceName", "Deployer"));
List<GCUBERunningInstance> results = client.execute(riquery,ServiceContext.getContext().getScope());
return results.get(0).getAccessPoint().getEndpoint("gcube/common/vremanagement/Deployer");
}
}

View File

@ -0,0 +1,61 @@
package org.gcube.vremanagement.resourcemanager.impl.deployment;
import java.util.HashMap;
import java.util.Map;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException;
/**
*
* Manager for {@link VirtualNode}s
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class VirtualNodeManager {
/** maps ghn ID to the related virtual node*/
private static Map<String, VirtualNode> nodes;
static { //at startup time, all the nodes are not working
if (nodes != null) {
for (VirtualNode node : nodes.values()) {
node.isNotWorking();
}
}
}
/**
* Gets or builds the VirtualNode
* @param ID the node identifier
* @param scope the deployment scope
* @return the Virtual Node
* @throws NoGHNFoundException if the node does not exist
*/
public static VirtualNode getNode(String ID, GCUBEScope scope) throws NoGHNFoundException {
checkNodes();
if (!nodes.containsKey(ID)) {
nodes.put(ID,new VirtualNode(ID, scope));
}
return nodes.get(ID);
}
/**
* Assigns the initial set of nodes to the manager.
* @param nodes the set of nodes
*/
public static void setNodes(Map<String, VirtualNode> nodes) {
VirtualNodeManager.nodes = nodes;
}
/**
* Checks the set of node, must be called before any usage of <code>nodes</code> to check if it has been initialized
*/
private static void checkNodes(){
if (nodes == null)
nodes = new HashMap<String, VirtualNode>();
}
}

View File

@ -0,0 +1,105 @@
package org.gcube.vremanagement.resourcemanager.impl.deployment.resources;
public class Dependency {
protected Service service = new Service();
protected String name;
protected String version;
/**
* @return the service
*/
public Service getService() {
return service;
}
/**
* @param service the service to set
*/
public void setService(Service service) {
this.service = service;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the version
*/
public String getVersion() {
return version;
}
/**
* @param version the version to set
*/
public void setVersion(String version) {
this.version = version;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((service == null) ? 0 : service.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
final Dependency other = (Dependency) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (service == null) {
if (other.service != null)
return false;
} else if (!service.equals(other.service))
return false;
if (version == null) {
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Dependency [name=" + name
+ ", version=" + version
+ ", service=" + service + "]";
}
}

View File

@ -0,0 +1,58 @@
package org.gcube.vremanagement.resourcemanager.impl.deployment.resources;
/**
* A package deployed by a Deployer service
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class DeployedDependency extends Dependency {
protected String host = "";
protected String status = "";
protected String message = "";
/**
* @return the host
*/
public String getHost() {
return host;
}
/**
* @param host the host to set
*/
public void setHost(String host) {
this.host = host;
}
/**
* @return the status
*/
public String getStatus() {
return status;
}
/**
* @param status the status to set
*/
public void setStatus(String status) {
this.status = status;
}
/**
* @return the message
*/
public String getMessage() {
return message;
}
/**
* @param message the message to set
*/
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,151 @@
package org.gcube.vremanagement.resourcemanager.impl.deployment.resources;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ServiceItem;
/**
* A GCUBE service
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class Service {
protected String clazz;
protected String name;
protected String version;
/** the gHN on which the servie is expected to be deployed */
protected String GHN = null;
public Service(String serviceClass, String serviceName, String serviceVersion) {
this.setClazz(serviceClass);
this.setName(serviceName);
this.setVersion(serviceVersion);
}
public Service() {}
public static Service fromServiceItem(ServiceItem item) {
Service s = new Service();
s.setClazz(item.getServiceClass());
s.setName(item.getServiceName());
s.setVersion(item.getServiceVersion());
if ((item.getGHN() != null) && (item.getGHN().compareToIgnoreCase("")!=0))
s.setGHN(item.getGHN());
return s;
}
/**
* @return the clazz
*/
public String getClazz() {
return clazz;
}
/**
* @param clazz the class to set
*/
public void setClazz(String clazz) {
this.clazz = clazz;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the version
*/
public String getVersion() {
return version;
}
/**
* @param version the version to set
*/
public void setVersion(String version) {
this.version = version;
}
/**
* @return the gHNID
*/
public String getGHN() {
return GHN;
}
/**
* @param ghn the gHN to set
*/
public void setGHN(String ghn) {
GHN = ghn;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((clazz == null) ? 0 : clazz.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Service other = (Service) obj;
if (clazz == null) {
if (other.clazz != null)
return false;
} else if (!clazz.equals(other.clazz))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (version == null) {
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Service [class=" + clazz
+ ", name=" + name
+ ", version=" + version + "]";
}
}

View File

@ -0,0 +1,69 @@
package org.gcube.vremanagement.resourcemanager.impl.operators;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.AddResourcesParameters;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ResourceList;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ServiceList;
/**
* A Resources Operator that coordinates the adding of resources to the scope
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class AddResourcesOperator extends Operator {
protected final GCUBELog logger = new GCUBELog(this, ServiceContext.getContext());
private AddResourcesParameters resourceList;
private OperatorConfig configuration;
/**
* Creates a new operator to manage the input resource list
*
* @param scopeState
* @param target
* @param operationID
*/
public AddResourcesOperator(OperatorConfig configuration, AddResourcesParameters resourceList){
this.resourceList = resourceList;
this.configuration = configuration;
}
/**
* {@inheritDoc}
*/
public void exec() throws Exception {
// deploy the services, if any
ServiceList services = resourceList.getServices();
if ((services == null) || (services.getService() == null) || (services.getService().length == 0)) {
logger.warn("The list of services to deploy is empty");
} else {
try {
new DeployServiceOperator(configuration, services, ACTION.ADD).run();
} catch (Exception e) {
logger.error("Unable to activate the deployment of the given service(s)", e);
throw new Exception("Unable to activate the deployment of the given service(s)", e);
}
}
//add the resources to the PublishedScopeResource, if any
ResourceList resources = resourceList.getResources();
if ((resources == null) || (resources.getResource() == null) || (resources.getResource().length == 0))
logger.warn("The list of resource to add is empty");
else {
try {
new ScopedResourceManagerOperator(configuration, resources, ACTION.ADD).run();
}catch (Exception e) {
logger.error("Unable to manage the given resource(s)", e);
throw new Exception("Unable to manage the given resource(s)", e);
}
}
//save the session
this.configuration.session.save();
}
}

View File

@ -0,0 +1,169 @@
package org.gcube.vremanagement.resourcemanager.impl.operators;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.queries.GCUBEServiceQuery;
import org.gcube.common.core.resources.GCUBEHostingNode;
import org.gcube.common.core.resources.GCUBEService;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.scope.GCUBEScope.Type;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ServiceItem;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ServiceList;
import org.gcube.vremanagement.resourcemanager.impl.brokerage.BrokerConnector;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Service;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STATUS;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
import org.gcube.vremanagement.resourcemanager.impl.state.Session.OPERATION;
/**
* A Deployer Operator that contacts the Deployer Services on the target nodes asking for the package deployment
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class DeployServiceOperator extends Operator {
/** Object logger */
protected final GCUBELog logger=new GCUBELog(this);
private ServiceList services;
private OperatorConfig configuration;
public DeployServiceOperator(OperatorConfig configuration, ServiceList services, ACTION action) {
this.services = services;
this.configuration = configuration;
this.action = action;
}
public void exec() throws Exception {
this.configuration.session.save();
Set<ScopedDeployedService> servicesToDeploy = new HashSet<ScopedDeployedService>();
Set<ScopedResource> servicesToUndeploy = new HashSet<ScopedResource>();
ISClient client = GHNContext.getImplementation(ISClient.class);
for (ServiceItem serviceitem : services.getService()) {
String serviceID = null;
try {
//retrieve the service ID from the IS
GCUBEServiceQuery query = client.getQuery(GCUBEServiceQuery.class);
query.addGenericCondition("$result/Profile/Name/string() eq '"+serviceitem.getServiceName()+
"' and $result/Profile/Class/string() eq '"+ serviceitem.getServiceClass() +"'");
List<GCUBEService> profiles = client.execute(query, this.configuration.scope);
if ((profiles == null) || (profiles.size() == 0)) {
logger.error("Failed to find the service");
continue;
}
logger.debug("Retrieved service ID " + profiles.get(0).getID() );
serviceID = profiles.get(0).getID();
} catch (Exception e) {
logger.error("Failed to retrieve the service ID from the IS ",e );
continue;
}
//build the related scoped resource
ScopedDeployedService service = (ScopedDeployedService) ScopedResourceFactory.newResource(serviceID, GCUBEService.TYPE, this.configuration.scope);
service.setSourceServiceName(Service.fromServiceItem(serviceitem));
try {
if (this.action == ACTION.ADD) {
service.findResource();//resolve the service deps
if (service.isSuccess())
servicesToDeploy.add(service);
} else {
service.setCallbackID(this.configuration.session.getId());
servicesToUndeploy.add(service);
}
} catch (Exception e) {
logger.warn("Failed to find the service",e);
}
this.configuration.session.addResource(service);
this.configuration.session.addService(service); //for the specific service section
}
//create the Deployment Plan with the Resource Broker
if ((this.action == ACTION.ADD) && this.allocate(servicesToDeploy)) {
Set<ScopedResource> resourcesToAdd = new HashSet<ScopedResource>();
for (ScopedDeployedService service : servicesToDeploy) {
if (service.getStatus() != STATUS.LOST) {
service.setCallbackID(this.configuration.session.getId());
resourcesToAdd.add(service);
if (this.configuration.scope.getType() == Type.VRE) {
//add also the target gHN to the scope
ScopedResource ghn = ScopedResourceFactory.newResource(service.getTargetGHNID(), GCUBEHostingNode.TYPE, this.configuration.scope);
resourcesToAdd.add(ghn);
this.configuration.session.addResource(ghn);
}
}
}
//add the services to the ScopeState (if any)
if(servicesToDeploy.size() > 0) {
this.configuration.scopeState.addResources(resourcesToAdd);
final GCUBEScope tscope = this.configuration.scope;
final Session tsession = this.configuration.session;
//periodically check if the feedback has to be sent to the broker
new Thread() {
@Override
public void run() {
while (true) {
try { Thread.sleep(5000);
} catch (InterruptedException e) {}
//logger.trace("ServiceOperator is checking if the session is closed");
if ((tsession.isReportClosed()
&& ((tsession.getOperation()==OPERATION.AddResources)
|| (tsession.getOperation()==OPERATION.UpdateResources)
|| (tsession.getOperation()==OPERATION.Create)))) {
try {
BrokerConnector.getBroker(tscope).sendFeedback(tsession);
} catch (Exception e) {
logger.error("Failed to send the feedback to the Broker", e);
}
break;
}
}
}
}.start();
}
}
//remove the services from the ScopeState (if any)
if(servicesToUndeploy.size() > 0)
this.configuration.scopeState.removeResources(servicesToUndeploy);
this.configuration.session.save();
}
/**
* Contacts the broker in order to allocate the given services
* @param servicesToDeploy the services to be deployed
* @return true if each service is correctly allocated, false otherwise
*/
private boolean allocate(Set<ScopedDeployedService> servicesToDeploy) {
try {
if (servicesToDeploy.size() > 0) {
BrokerConnector.getBroker(this.configuration.scope).makePlan(this.configuration.session, servicesToDeploy, services.getGHN());
this.configuration.session.reportBrokerWork(true, "The Deployment Plan was successfully created");
return true;
} else {
logger.warn("The Broker was not contacted. After the dependency resolution phase, there is nothing to deploy");
this.configuration.session.reportBrokerWork(false, "The Broker was not contacted. After the dependency resolution phase, there is nothing to deploy");
return true;
}
} catch (Exception e) {
logger.error("An error occurred when interacting with the broker", e);
this.configuration.session.reportBrokerWork(false, "An error occurred when interacting with the broker " + e.getMessage());
return false;
}
}
}

View File

@ -0,0 +1,49 @@
package org.gcube.vremanagement.resourcemanager.impl.operators;
import java.util.HashSet;
import java.util.Set;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STATUS;
/**
*
* Dispose the entire scope
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class DisposeScopeOperator extends Operator {
protected final GCUBELog logger = new GCUBELog(this, ServiceContext.getContext());
private OperatorConfig configuration;
public DisposeScopeOperator(OperatorConfig configuration) {
this.configuration = configuration;
}
@Override
public void exec() throws Exception {
//exclude from the resources to remove the Services' resources. This is because we also have the
//related Running Instances in the list, and we will eventually undeploy them (if # scopes ==1)
Set<ScopedResource> resources = new HashSet<ScopedResource>();
for (ScopedResource resource : this.configuration.scopeState.getAllResources()) {
if ((resource.getType().compareTo(ScopedDeployedService.TYPE) != 0)
&& (resource.getStatus() != STATUS.UNPUBLISHED)
&& (resource.getStatus() != STATUS.LOST)
&& (resource.getStatus() != STATUS.REMOVED)){
resources.add(resource);
this.configuration.session.addResource(resource);
}
}
configuration.scopeState.removeResources(resources);
//TODO: should we also undeploy the RM itself?
this.configuration.session.save();
}
}

View File

@ -0,0 +1,45 @@
package org.gcube.vremanagement.resourcemanager.impl.operators;
import org.gcube.common.core.utils.logging.GCUBELog;
/**
*
* Base class for manager's operators
* .
* A manage operator is devoted to execute certain assigned tasks.
* The {@link #exec()} method is asynchronously called
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public abstract class Operator {
protected final GCUBELog logger=new GCUBELog(this.getClass());
protected ACTION action;
protected OperatorConfig configuration;
public enum ACTION {ADD,REMOVE}
public final void run() {
//new Thread() {
// public void run() {
try {
Operator.this.exec();
} catch (Exception e) {
logger.error("The operator was unable to manage the request",e);
}
// }
//}.start();
}
/**
* Executes the operator's tasks
*
* @throws Exception if any of the tasks fails
*/
public abstract void exec() throws Exception;
}

View File

@ -0,0 +1,28 @@
package org.gcube.vremanagement.resourcemanager.impl.operators;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.state.ScopeState;
import org.gcube.vremanagement.resourcemanager.impl.state.Session;
/**
* Basic configuration for every {@link Operator}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class OperatorConfig {
public final Session session;
public final GCUBEScope scope;
public final ScopeState scopeState;
public OperatorConfig(Session report, ScopeState scopeState, GCUBEScope ... scope) {
this.session = report;
this.scopeState = scopeState;
this.scope = (scope!=null && scope.length >0)? scope[0] : ServiceContext.getContext().getScope();
}
}

View File

@ -0,0 +1,57 @@
package org.gcube.vremanagement.resourcemanager.impl.operators;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.RemoveResourcesParameters;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ResourceList;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ServiceList;
/**
* A Resources Operator that coordinates the removal of resources from the scope
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class RemoveResourcesOperator extends Operator {
protected final GCUBELog logger = new GCUBELog(this, ServiceContext.getContext());
private OperatorConfig configuration;
private RemoveResourcesParameters resourceList;
public RemoveResourcesOperator(OperatorConfig configuration, RemoveResourcesParameters resourceList) {
this.configuration = configuration;
this.resourceList = resourceList;
}
public void exec() throws Exception {
// undeploy the services, if any
ServiceList services = resourceList.getServices();
if ((services == null) || (services.getService() == null) || (services.getService().length == 0)) {
logger.warn("The list of services to undeploy is empty");
} else {
try {
new DeployServiceOperator(configuration, services, ACTION.REMOVE).run();
} catch (Exception e) {
logger.error("Unable to activate the undeployment of the given service(s)", e);
throw new Exception("Unable to activate the undeployment of the given service(s)", e);
}
}
//removes the resources from the PublishedScopeResource, if any
ResourceList resources = resourceList.getResources();
if ((resources == null) || (resources.getResource().length == 0))
logger.warn("The list of resource to add is empty");
else {
try {
new ScopedResourceManagerOperator(configuration, resources, ACTION.REMOVE).run();
}catch (Exception e) {
logger.error("Unable to manage the given resource(s)", e);
throw new Exception("Unable to manage the given resource(s)", e);
}
}
}
}

View File

@ -0,0 +1,59 @@
package org.gcube.vremanagement.resourcemanager.impl.operators;
import java.util.HashSet;
import java.util.Set;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ResourceItem;
import org.gcube.vremanagement.resourcemanager.stubs.resourcemanager.ResourceList;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory;
/**
* Add and remove list of {@link ScopedResource}s to/from a given scope
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class ScopedResourceManagerOperator extends Operator {
private ResourceList resources;
public ScopedResourceManagerOperator(OperatorConfig configuration, ResourceList resources, ACTION action) {
this.configuration = configuration;
this.resources = resources;
this.action = action;
}
public void exec() throws Exception {
Set<ScopedResource> toadd = new HashSet<ScopedResource>();
Set<ScopedResource> toremove = new HashSet<ScopedResource>();
ScopedResource sresource = null;
for (ResourceItem resource : this.resources.getResource()) {
try {
sresource = ScopedResourceFactory.newResource(resource.getID(), resource.getType(), this.configuration.scope);
if (this.action == ACTION.ADD) {
logger.info("Adding resource " + sresource.getId() + " (" + sresource.getType() + ") to scope " + this.configuration.scope.toString());
toadd.add(sresource);
} else if (this.action == ACTION.REMOVE) {
logger.info("Removing resource " + sresource.getId() + " (" + sresource.getType() + ") from scope " + this.configuration.scope.toString());
toremove.add(sresource);
}
//add the resource item to the session
this.configuration.session.addResource(sresource);
} catch (Exception e) {
logger.error("Unable to manage the resource",e);
}
}
if(toadd.size() > 0)
configuration.scopeState.addResources(toadd);
if(toremove.size() > 0)
configuration.scopeState.removeResources(toremove);
this.configuration.session.save();
}
}

View File

@ -0,0 +1,129 @@
package org.gcube.vremanagement.resourcemanager.impl.resources;
import java.util.List;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.resources.GCUBECS;
import org.gcube.common.core.resources.GCUBECSInstance;
import org.gcube.common.core.resources.GCUBECollection;
import org.gcube.common.core.resources.GCUBEExternalRunningInstance;
import org.gcube.common.core.resources.GCUBEGenericResource;
import org.gcube.common.core.resources.GCUBEMCollection;
import org.gcube.common.core.resources.GCUBEResource;
import org.gcube.common.core.resources.GCUBERuntimeResource;
import org.gcube.common.core.resources.GCUBEService;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.ISTemplateQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBECSInstanceQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBECSQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBECollectionQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBEExternalRIQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGenericResourceQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBEMCollectionQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBERuntimeResourceQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBEServiceQuery;
import org.gcube.common.core.informationsystem.publisher.ISPublisher;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
*
* Models a generic scoped {@link GCUBEResource}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class ScopedAnyResource extends ScopedResource {
@XStreamOmitField
GCUBEResource profile = null;
@XStreamOmitField
@SuppressWarnings("unchecked")
Class profileClass = null;
protected ScopedAnyResource(String id, String type, GCUBEScope scope) {
super(id, type, scope);
}
/**
* Gets the profile of the Scoped Resource
* @throws Exception if the resource was not found
*/
@Override
@SuppressWarnings({ "unchecked", "rawtypes"})
protected void find() throws Exception {
try {
ISClient client = GHNContext.getImplementation(ISClient.class);
Class query = null;
if (this.type.compareToIgnoreCase(GCUBECollection.TYPE) == 0) {query = GCUBECollectionQuery.class; profileClass = GCUBECollection.class;}
else if (this.type.compareToIgnoreCase(GCUBEMCollection.TYPE) == 0) {query = GCUBEMCollectionQuery.class; profileClass = GCUBEMCollection.class;}
else if (this.type.compareToIgnoreCase(GCUBEGenericResource.TYPE) == 0) {query = GCUBEGenericResourceQuery.class; profileClass = GCUBEGenericResource.class;}
else if (this.type.compareToIgnoreCase(GCUBEExternalRunningInstance.TYPE) == 0) {query = GCUBEExternalRIQuery.class; profileClass = GCUBEExternalRunningInstance.class;}
else if (this.type.compareToIgnoreCase(GCUBECS.TYPE) == 0) {query = GCUBECSQuery.class; profileClass = GCUBECS.class;}
else if (this.type.compareToIgnoreCase(GCUBECSInstance.TYPE) == 0) {query = GCUBECSInstanceQuery.class; profileClass = GCUBECSInstance.class;}
else if (this.type.compareToIgnoreCase(GCUBEService.TYPE) == 0) {query = GCUBEServiceQuery.class; profileClass = GCUBEService.class;}
else if (this.type.compareToIgnoreCase(GCUBERuntimeResource.TYPE) == 0) {query = GCUBERuntimeResourceQuery.class; profileClass = GCUBERuntimeResource.class;}
else throw new Exception("Unknown resource type: " + this.type);
ISTemplateQuery realquery = (ISTemplateQuery) client.getQuery(query);
realquery.addAtomicConditions(new AtomicCondition("//ID",this.id));
List <GCUBEResource> profiles = client.execute(realquery, GCUBEScope.getScope(this.scope));
if ((profiles != null) && (profiles.size() > 0))
this.profile = profiles.get(0);
else
// obviously, in the case of adding, the resource is not in the current scope, therefore we look upstairs (the enclosing scope)
this.profile = (GCUBEResource) client.execute(realquery, GCUBEScope.getScope(this.scope).getEnclosingScope()).get(0);
} catch (Exception e) {
throw new Exception("unable to find the target resource (ID=" + id + "). Possible cause: " + e.getMessage(), e);
}
}
@Override
protected void addToScope() throws ResourceNotFound, Exception {
this.findResource();
getLogger().debug("Adding scope to resource profile");
try {
profile.addScope(this.getScope());
//republish the resource
ISPublisher publisher = GHNContext.getImplementation(ISPublisher.class);
publisher.updateGCUBEResource(this.profile, ServiceContext.getContext().getScope(), ServiceContext.getContext());
//republish also in the infrastructure scope, if needed
if (ServiceContext.getContext().getScope().getType() == GCUBEScope.Type.VO) {
if (this.profile.getScopes().values().contains(ServiceContext.getContext().getScope().getEnclosingScope())) {
publisher.updateGCUBEResource(this.profile, ServiceContext.getContext().getScope().getEnclosingScope(), ServiceContext.getContext());
}
}
} catch (Exception e) {
this.noHopeForMe("Failed to add the scope ("+ this.getScope()+") to resource " + this.getId(), e);
}
}
@Override
protected void removeFromScope() throws ResourceNotFound, Exception {
this.findResource();
getLogger().debug("Removing scope from resource profile");
try {
profile.removeScope(this.getScope());
//republish the resource
ISPublisher publisher = GHNContext.getImplementation(ISPublisher.class);
publisher.updateGCUBEResource(this.profile, ServiceContext.getContext().getScope(), ServiceContext.getContext());
//republish also in the infrastructure scope, if needed
if (ServiceContext.getContext().getScope().getType() == GCUBEScope.Type.VO) {
if (this.profile.getScopes().values().contains(ServiceContext.getContext().getScope().getEnclosingScope())) {
publisher.updateGCUBEResource(this.profile, ServiceContext.getContext().getScope().getEnclosingScope(), ServiceContext.getContext());
}
}
} catch (Exception e) {
this.noHopeForMe("Failed to remove the scope ("+ this.getScope()+") from resource " + this.getId(), e);
}
}
}

View File

@ -0,0 +1,397 @@
package org.gcube.vremanagement.resourcemanager.impl.resources;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.gcube.common.core.resources.GCUBEService;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.vremanagement.deployer.stubs.common.PackageInfo;
import org.gcube.vremanagement.resourcemanager.impl.deployment.SoftwareGatewayRequest;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Dependency;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Service;
import org.gcube.vremanagement.resourcemanager.impl.operators.Operator.ACTION;
/**
*
* Models a scoped {@link GCUBEService}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class ScopedDeployedService extends ScopedResource {
public static final String TYPE = GCUBEService.TYPE;
/** Target port-type name. */
protected static final String REPOSITORY_ENDPOINT = "gcube/vremanagement/softwarerepository/SoftwareRepository";
/** Target service name. */
protected static final String REPOSITORY_NAME = "SoftwareRepository";
/** Target service class. */
protected static final String REPOSITORY_CLASS = "VREManagement";
/** Timeout in millisecs for the channel with the Software Repository instance */
protected static final int TIMEOUT = 600000;
/** resolved dependencies */
private List<Dependency> resolved = new ArrayList<Dependency>();
/** missing dependency */
private List<Dependency> missing = new ArrayList<Dependency>();
/** the packages deployed for this service*/
private Map <String, List<Dependency>> node2packages = new HashMap<String, List<Dependency>>();
/** the packages deployed for this service*/
private Map <String, List<Dependency>> node2missing = new HashMap<String, List<Dependency>>();
private Service service;
private String lastActivityOnGHN;
//the target ghn(s)
private List<VirtualNode> virtualNodes = new ArrayList<VirtualNode>();
/** maps node with the scope used when deploying there */
private Map<String, String> node2scope = new HashMap<String, String>();
/** maps RI id with the ghn id (where the instance is deployed on*/
private Map<String, String> ri2ghn = new HashMap<String, String>();
protected ScopedDeployedService(String id, GCUBEScope scope) {
super(id, TYPE, scope);
}
public void setSourceServiceName(Service service) {
this.service = service;
}
public Service getSourceService() {
return this.service;
}
/**
* Gets the list of resolved dependencies when the deployment was performed
* on a specific node
*
* @param ghnid the ID of the node
* @return the resolved dependencies
*/
public List<Dependency> getResolvedDependencies(String ghnid) {
if (node2packages.get(ghnid) == null)
return Collections.emptyList();
return Collections.unmodifiableList(node2packages.get(ghnid));
}
/**
* Gets the list of resolved dependencies to be used in the next deployment
*
* @return the resolved dependencies
*/
public List<Dependency> getLastResolvedDependencies() {
return this.resolved;
}
/**
* Sets the list of resolved dependencies to be used in the next deployment
*
* @param dependencies the resolved dependencies
*/
public void setResolvedDependencies(List<Dependency> dependencies) {
this.resolved = dependencies;
}
/**
* Gets the list of missing dependencies when the deployment was performed
* on a specific node
*
* @param ghnid the ID of the node
* @return the missing dependencies
*/
public List<Dependency> getMissingDependencies(String ghnid) {
if (node2missing.get(ghnid) == null)
return Collections.emptyList();
return Collections.unmodifiableList(node2missing.get(ghnid));
}
/**
* Gets the list of missing dependencies for the last (failed) deployment
*
* @return the missing dependencies
*/
public List<Dependency> getLastMissingDependencies() {
return this.missing;
}
/**
* Sets the list of missing dependencies for the next deployment
*
* @param dependencies the missign dependencies
*/
public void setMissingDependencies(List<Dependency> dependencies) {
///this.getLogger().trace("Setting missing deps " + dependencies.size());
missing= dependencies;
}
@Override
protected void find() throws Exception {
//looks for the service and its deps in the Software Repository
SoftwareGatewayRequest request = new SoftwareGatewayRequest();
request.addService(this);
this.setErrorMessage(""); //empty any previous message
try {
request.send();
if (this.resolved.size() == 0) {
this.success = false;
this.setErrorMessage("Invalid list of dependecies retrieved from the Software Repository");
} else if (this.missing.size() > 0) {//ops, some deps are missing!
this.success = false;
this.setErrorMessage("The service cannot be deployed due to one or more missing dependencies: " + this.missing);
} else {
this.success = true;
}
} catch (Exception e) {
this.success= false;
this.setErrorMessage("Unable to resolve the list of dependencies for this service " + e.getMessage());
getLogger().error("Unable to resolve the list of deps for " + this.service, e);
throw new Exception("Unable to resolve the list of dependencies for " + this.service, e);
}
}
@Override
protected void addToScope() throws ResourceNotFound, Exception {
logger.trace("This service belongs to " + this.scope);
if (!this.isSuccess()) {
this.noHopeForMe(this.getErrorMessage(),new Exception());
}
if ((this.lastActivityOnGHN == null) || (this.lastActivityOnGHN.compareTo("")==0)) {
this.noHopeForMe("Unable to find a suitable target gHN where to deploy the service",new Exception());
}
this.action = ACTION.ADD;
this.setErrorMessage(""); //empty any previous message
Exception lastException = null;
//deploy the service
List<VirtualNode> nodesToRemove = new ArrayList<VirtualNode>();
for (VirtualNode node : this.virtualNodes) {
try {
node.deploy(this.getScope());
//store packages for future undeployment and reporting purposes
List<Dependency> resolvedPackages = new ArrayList<Dependency>();
for (Dependency dep : this.resolved)
resolvedPackages.add(dep);
node2packages.put(node.getID(), resolvedPackages);
//store missing packages for reporting purposes
List<Dependency> missingPackages = new ArrayList<Dependency>();
for (Dependency dep : this.missing)
missingPackages.add(dep);
if (node2missing == null) {
logger.trace("node2missing is null");
node2missing = new HashMap<String, List<Dependency>>(); // this is here for backwards compatibility
}
node2missing.put(node.getID(), missingPackages);
} catch (Exception e) {
nodesToRemove.add(node);
logger.error("Failed to deploy on " + node.getID(), e);
logger.info("Virtual Node " + node.toString() + " will be removed from the queue");
lastException=e;
}
}
this.missing.clear();
this.resolved.clear();
if (nodesToRemove.size() > 0 ) {
this.virtualNodes.removeAll(nodesToRemove);
this.noHopeForMe("Unable to contact the target gHN ("+ this.lastActivityOnGHN +") where to deploy the service",lastException);
}
}
@Override
protected void removeFromScope() throws ResourceNotFound, Exception {
logger.trace("This service belongs to " + this.scope);
if (!this.isSuccess()) {
//TODO: could we undeploy static packages here?
this.noHopeForMe(this.getErrorMessage(),new Exception());
}
if ((this.lastActivityOnGHN == null) || (this.lastActivityOnGHN.compareTo("")==0)) {
this.noHopeForMe("Unable to find a valid target gHN where to undeploy the service", new Exception());
}
this.setErrorMessage(""); //empty any previous message
//undeploy the service from all the virtual nodes where it was deployed (if any)
this.action = ACTION.REMOVE;
try {
for (VirtualNode node : this.virtualNodes) {
try {
if (node2scope.containsKey(node.getID()))
node.undeploy(GCUBEScope.getScope(node2scope.get(node.getID())));
else
node.undeploy(this.getScope()); //try the service's scope
} catch (Exception e) {
this.noHopeForMe("Failed to undeploy from "+ node ,e);
}
}
this.virtualNodes.clear();
} catch (Exception e) {
this.noHopeForMe("Unable to contact the target gHN ("+ this.lastActivityOnGHN +") where to undeploy the service, deployer says" + e.getMessage() ,e);
}
}
/**
* Schedules the undeployment of all the instances of this service from scope
*
* @throws Exception if the operation fails
*/
public void scheduleUndeploy() {
for (VirtualNode node : this.virtualNodes)
scheduleUndeploy(node);
}
/**
* Schedules the undeployment of an instance of this service from the node
*
* @param node the node from where to undeploy the service
* @throws Exception if the operation fails
*/
public void scheduleUndeploy(VirtualNode node) {
getLogger().info("Scheduling undeployment of service "+ this.service+ " from GHN " + this.lastActivityOnGHN);
//notify the node to operate in the scope previously used for the deployment
this.checkNode2Scope();
if (node2scope.containsKey(node.getID())) //it has to be in, but it couldn't if the service was deployed from a previous (version < 1.1)RM instance
node.setWorkingScope(GCUBEScope.getScope(node2scope.get(node.getID())));
//prepare the input list of packagesToAdd for that GHN
List<Dependency> deps = node2packages.get(node.getID());
if (deps == null)
return;
Set<PackageInfo> packages = new HashSet<PackageInfo>();
for (int i = 0; i < deps.size(); i++) {
PackageInfo p = new PackageInfo();
p.setServiceName(deps.get(i).getService().getName());
p.setServiceClass(deps.get(i).getService().getClazz());
p.setServiceVersion(deps.get(i).getService().getVersion());
p.setVersion(deps.get(i).getVersion());
p.setName(deps.get(i).getName());
getLogger().trace("Adding Package to undeployment request: " + deps.get(i));
packages.add(p);
}
node.setPackagesToRemove(packages);
this.lastActivityOnGHN = node.getID();
}
/**
* Undeploys any instances of this service from the given gHN
*
* @param lastActivityOnGHN the id of the gHN from where to undeploy the service
* @throws Exception
*/
public void removeFromScope(String ghnID) throws VirtualNode.NoGHNFoundException, Exception {
logger.trace("This service belongs to " + this.scope);
this.action = ACTION.REMOVE;
for (VirtualNode node : this.virtualNodes)
if (node.getID().compareToIgnoreCase(ghnID) == 0) {
checkNode2Scope();
if (node2scope.containsKey(ghnID))
node.undeploy(GCUBEScope.getScope(node2scope.get(ghnID)));
else
node.undeploy(this.getScope()); //try the service's scope
this.virtualNodes.remove(node);
return;
}
this.noHopeForMe("Unable to find the gHN with id " + this.lastActivityOnGHN +
" to undeploy the instance of the " + this.service, new VirtualNode.NoGHNFoundException(""));
}
/**
* Sets the GHN where the service will be deployed
*
* @param node the target GHN
*/
public void setTargetGHN(VirtualNode node) {
getLogger().info("Using GHN " + node.getID() + " for " + this);
Set<PackageInfo> packages = new HashSet<PackageInfo>();
//prepare the input list of packagesToAdd for that GHN
List<Dependency> deps = this.resolved;
for (int i = 0; i < deps.size(); i++) {
PackageInfo p = new PackageInfo();
p.setServiceName(deps.get(i).getService().getName());
p.setServiceClass(deps.get(i).getService().getClazz());
p.setServiceVersion(deps.get(i).getService().getVersion());
p.setVersion(deps.get(i).getVersion());
p.setName(deps.get(i).getName()); //packageName
getLogger().trace("Adding Package to deployment request: " + deps.get(i));
packages.add(p);
}
node.setPackagesToAdd(packages);
this.checkNode2Scope();//for backward compatibility (version <= 1.1)
node2scope.put(node.getID(), node.getWorkingScope().toString());
this.virtualNodes.add(node);
this.lastActivityOnGHN = node.getID();
}
/**
* Gets the ID of the target gHN
* @return the ID of the target gHN
*/
public String getTargetGHNID() {
return lastActivityOnGHN; //this.virtualNodes.size() > 0 ? this.virtualNodes.get(0).getID() : "";
}
/**
* Gets the ID of the target gHN
* @return the ID of the target gHN
*/
public String getTargetGHN() {
return this.virtualNodes.size() > 0 ? this.virtualNodes.get(0).getID() : "";
}
public void setRIonGHN(String ri, String ghn) {
this.ri2ghn.put(ri, ghn);
}
/**
* Sets the callback ID from now on for all the service's operations
* @param id the callback ID
*/
public void setCallbackID(String id) {
for (VirtualNode node : this.virtualNodes)
node.setCallbackID(id);
}
/**
* Gets the list of {@link VirtualNode}s where the service is actually deployed within this scope
* @return the list of {@link VirtualNode}s
*/
public List<VirtualNode> getNodes() {
return this.virtualNodes;
}
/**
* Number of times the resource is searched in the IS before to declare it lost
* @return the number of attempts to do
*/
@Override
protected int getMaxFindAttempts(){
return 3;
}
private void checkNode2Scope(){
//this is for backward compatibility, if the obj is loaded from an old serialization
//node2scope could not be initialized
if (this.node2scope == null)
this.node2scope = new HashMap<String, String>();
}
}

View File

@ -0,0 +1,129 @@
package org.gcube.vremanagement.resourcemanager.impl.resources;
import java.util.List;
import org.apache.axis.message.addressing.Address;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.gcube.common.core.contexts.GCUBERemotePortTypeContext;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.ISClient.ISUnsupportedQueryException;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGHNQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBERIQuery;
import org.gcube.common.core.resources.GCUBEHostingNode;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.vremanagement.ghnmanager.stubs.AddScopeInputParams;
import org.gcube.common.vremanagement.ghnmanager.stubs.GHNManagerPortType;
import org.gcube.common.vremanagement.ghnmanager.stubs.service.GHNManagerServiceAddressingLocator;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
/**
* Models a scoped {@link GCUBEHostingNode}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class ScopedGHN extends ScopedResource {
public static final String TYPE = GCUBEHostingNode.TYPE;
private String nodename = "";
private transient EndpointReferenceType ghnEpr;
protected ScopedGHN(String id, GCUBEScope scope) {
super(id, TYPE, scope);
}
@Override
protected void addToScope() throws ResourceNotFound, Exception {
if (this.ghnEpr == null)
this.findResource();
//contact the GHNManager to add the GHN to the given scope
EndpointReferenceType endpoint = new EndpointReferenceType();
try {
endpoint.setAddress(new Address("http://"+ this.nodename +"/wsrf/services/gcube/common/vremanagement/GHNManager"));
GHNManagerServiceAddressingLocator locator = new GHNManagerServiceAddressingLocator();
GHNManagerPortType pt = GCUBERemotePortTypeContext.getProxy(locator.getGHNManagerPortTypePort(endpoint),
ServiceContext.getContext().getScope().getEnclosingScope(), ServiceContext.getContext());
AddScopeInputParams params = new AddScopeInputParams();
params.setScope(this.scope.toString());
params.setMap(""); //eventually, set here the new Service Map
pt.addScope(params);
} catch (Exception e) {
this.noHopeForMe("Failed to add GHN to scope " + scope.toString(), e);
}
}
@Override
protected void find() throws Exception {
ISClient client = null;
GCUBEGHNQuery query = null;
try {
client = GHNContext.getImplementation(ISClient.class);
query = client.getQuery(GCUBEGHNQuery.class);
query.addAtomicConditions(new AtomicCondition("/ID/text()", this.id));
} catch (Exception e) {
throw new Exception("unable to query of the target GHN (ID=" + this.id + ")", e);
}
try {
List<GCUBEHostingNode> hostingNodes = client.execute(query, ServiceContext.getContext().getScope());
this.nodename = hostingNodes.get(0).getNodeDescription().getName();
this.hostedOn = nodename;
this.ghnEpr = this.loadGHNmanager(hostingNodes.get(0).getID(), client, ServiceContext.getContext().getScope());
} catch (Exception e) {
//try in the enclosing scope
try {
List<GCUBEHostingNode> hostingNodes = client.execute(query, ServiceContext.getContext().getScope().getEnclosingScope());
this.nodename = hostingNodes.get(0).getNodeDescription().getName();
this.hostedOn = nodename;
this.ghnEpr = this.loadGHNmanager(hostingNodes.get(0).getID(), client,ServiceContext.getContext().getScope().getEnclosingScope());
} catch (Exception ei) {
throw new Exception("unable to find the target GHN (ID=" + this.id + ")", e);
}
}
}
@Override
protected void removeFromScope() throws ResourceNotFound, Exception {
if (this.ghnEpr == null)
this.findResource();
//EndpointReferenceType endpoint = new EndpointReferenceType();
try {
//endpoint.setAddress(new Address("http://"+ this.nodename +"/wsrf/services/gcube/common/vremanagement/GHNManager"));
GHNManagerServiceAddressingLocator locator = new GHNManagerServiceAddressingLocator();
GHNManagerPortType pt = GCUBERemotePortTypeContext.getProxy(locator.getGHNManagerPortTypePort(this.ghnEpr),
ServiceContext.getContext().getScope().getEnclosingScope(), ServiceContext.getContext());
pt.removeScope(this.scope.toString());
} catch (Exception e) {
this.noHopeForMe("Failed to remove GHN from scope " + scope.toString(), e);
}
}
/**
* Looks for the GHN manager's endpoint to contact
* @param id the identifier of the gHN
* @param client the ISClient instance to use
* @param scope
* @return the endpoint reference of gHNManager's portType to contact
* @throws Exception if the search fails
*/
private EndpointReferenceType loadGHNmanager(String id, ISClient client, GCUBEScope scope) throws Exception {
//looks for the GHN manager's endpoint to contact
GCUBERIQuery riquery = client.getQuery(GCUBERIQuery.class);
riquery.addAtomicConditions(new AtomicCondition("//GHN/@UniqueID", id),
new AtomicCondition("//ServiceClass", "VREManagement"),
new AtomicCondition("//ServiceName", "GHNManager"));
List<GCUBERunningInstance> results = client.execute(riquery,scope);
return results.get(0).getAccessPoint().getEndpoint("gcube/common/vremanagement/GHNManager");
}
}

View File

@ -0,0 +1,332 @@
package org.gcube.vremanagement.resourcemanager.impl.resources;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.gcube.common.core.resources.GCUBEResource;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.operators.Operator.ACTION;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
* An abstract model for a scoped {@link GCUBEResource}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public abstract class ScopedResource {
/** Object getLogger() */
@XStreamOmitField
protected GCUBELog logger;
/** the resource identifier*/
protected String id;
/** the resource type */
protected String type;
/** where the resource is hosted on, it makes sense for RI, GHN*/
protected String hostedOn = "";
/** result of the last operation performed on the resource */
protected boolean success;
/** the error message, if any, from the last operation */
protected String errorMessage = "";
protected String scope;
/** the last action performed on the resource*/
protected ACTION action;
/** Last modification time stamp*/
protected Date lastModificationTime;
/** Last modification time stamp*/
protected Date jointTime;
/** the current status of the resource */
protected STATUS status;
/** resource's legal statuses */
public static enum STATUS {
CREATED() {public List<STATUS> previous() {return Collections.emptyList();}},
ADDREQUESTED() {public List<STATUS> previous() {return Collections.unmodifiableList(Arrays.asList(CREATED));}},
ADDED() {public List<STATUS> previous() {return Collections.unmodifiableList(Arrays.asList(ADDREQUESTED));}},
PUBLISHED() {public List<STATUS> previous() {return Collections.unmodifiableList(Arrays.asList(ADDED));}},
REMOVEREQUESTED() {public List<STATUS> previous() {return Collections.unmodifiableList(Arrays.asList(ADDED, PUBLISHED));}},
REMOVED() {public List<STATUS> previous() {return Collections.unmodifiableList(Arrays.asList(REMOVEREQUESTED));}},
UNPUBLISHED () {public List<STATUS> previous() {return Collections.unmodifiableList(Arrays.asList(REMOVED));}},
LOST () {public List<STATUS> previous() {return Collections.unmodifiableList(Arrays.asList(REMOVED,REMOVEREQUESTED,ADDED,PUBLISHED,CREATED,UNPUBLISHED));}};
abstract public List<STATUS> previous();
}
public ScopedResource(String id, String type, GCUBEScope scope) {
this.id = id;
this.type = type;
this.scope = scope.toString();
this.status = STATUS.CREATED;
}
/**
* Custom
*
* @throws ResourceNotFound if it is impossible to locate the resource
*/
protected abstract void find() throws Exception;;
/**
* Looks for the resource in the infrastructure
*
* @throws ResourceNotFound if it is impossible to locate the resource
*/
public synchronized void findResource() throws ResourceNotFound {
this.setErrorMessage(""); //empty any previous message
int max_attempts = this.getMaxFindAttempts(); //try to find the resource 5 times
int i = 0;
while (true) {
try {
this.find();
this.success = true;
break;
} catch (Exception e) {
logger.warn("Can't find resource "+ this + " on the IS");
if (i++ <= max_attempts) {
logger.warn("try again in 5 secs");
try {Thread.sleep(5000);} catch (InterruptedException e1) {}
continue;
}
else {
this.noHopeForMe("Can't find resource "+ this + " on the IS", new ResourceNotFound(e));
break;
}
}
}
}
public synchronized void doAction(ACTION action) throws ResourceNotFound, Exception {
this.action = action;
switch (action) {
case ADD: this.addToScope(); this.setJointTime(Calendar.getInstance().getTime()); this.success= true; break;
case REMOVE: this.removeFromScope(); this.success= true; break;
default: break;
}
this.setChanged();
}
/**
* Adds the resource to the scope
* @throws Exception if the operation fails
* @throws ResourceNotFound if the resource does not exist in the infrastructure
*/
protected abstract void addToScope() throws ResourceNotFound, Exception;
/**
* Removes the resource from the scope
* @throws Exception if the operation fails
* @throws ResourceNotFound if the resource does not exist in the infrastructure
*/
protected abstract void removeFromScope() throws ResourceNotFound, Exception;
/**
* @return the resource ID
*/
public String getId() {
return id;
}
/**
* @return the resource type
*/
public String getType() {
return type;
}
/**
* @return the scope
*/
public final GCUBEScope getScope() {
return GCUBEScope.getScope(this.scope);
}
protected final void setScope(GCUBEScope scope) {
this.scope = scope.toString();
}
/**
* @return the action
*/
public ACTION getAction() {
return action;
}
/**
* @return the errorMessage
*/
public String getErrorMessage() {
return errorMessage;
}
/**
* @param errorMessage the errorMessage to set
*/
public void setErrorMessage(String errorMessage) {
this.success = false;
this.errorMessage = errorMessage;
}
/**
* Updates the time the resource joined the scope
* @param time the new joint time
*/
public void setJointTime(Date time) {
this.jointTime = time;
}
private void setChanged() {
this.setLastModificationTime(Calendar.getInstance().getTime());
}
/**
* @return the success
*/
public boolean isSuccess() {
return success;
}
/**
* @return the node on which the Scope is hosted
*/
public String getHostedOn() {
return hostedOn;
}
public void setHostedON(String hostedOn) {
this.hostedOn = hostedOn;
}
public Date getJointTime() {
if (jointTime == null)
jointTime = Calendar.getInstance().getTime();
return jointTime;
}
public Date getLastModificationTime() {
if (lastModificationTime == null)
this.setChanged();
return lastModificationTime;
}
private void setLastModificationTime(Date lastModificationTime) {
this.lastModificationTime = lastModificationTime;
}
/**
* @return the status
*/
public STATUS getStatus() {
return status;
}
/**
* @param status the status to set
*/
public synchronized void setStatus(STATUS status) {
getLogger().trace(this.toString()+ ": status set to " + status);
this.status = status;
}
/**
* Number of times the resource is searched in the IS before to declare it lost
* @return
*/
protected int getMaxFindAttempts(){
return 5;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ScopedResource other = (ScopedResource) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
/**
* Gives up the operation on the resource
* @param message the error message to return
* @param e the exception that generates the hopeless
* @throws E the source exception
*/
protected <E extends Exception> void noHopeForMe(String message, E e) throws E {
getLogger().error(this.toString() +": Unable to manage the resource " + message ,e);
this.setStatus(STATUS.LOST);
this.success = false;
this.setErrorMessage(message);
throw e;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "Resource [id=" + id
+ ", type=" + type
+ ", timestamp=" + lastModificationTime
+ ", scope=" + scope
+ ", status=" + status
+ " hostedOn=" + hostedOn + "]";
}
protected GCUBELog getLogger() {
if (this.logger == null)
logger=new GCUBELog(this);
return logger;
}
/** Unable to find the resource in the infrastructure*/
public class ResourceNotFound extends Exception {
public ResourceNotFound(String message) {super(message);}
public ResourceNotFound(Exception e) {
super(e);
}
private static final long serialVersionUID = -6111206113583291172L;
}
}

View File

@ -0,0 +1,85 @@
package org.gcube.vremanagement.resourcemanager.impl.resources;
import org.gcube.common.core.resources.GCUBEHostingNode;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.resources.GCUBEService;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.state.ScopeState;
public class ScopedResourceFactory {
protected static GCUBELog logger = new GCUBELog(ScopedResourceFactory.class);
private static ScopeState scopeState = null;
public static void setResourceList(final ScopeState list) {
scopeState = list;
}
/**
* Creates a new {@link ScopedResource}
*
* @param id the gCube Resource identifier
* @param type the resource type
* @param scope the {@link GCUBEScope} assigned to the resource
* @return the resource
*/
public static ScopedResource newResource(String id, String type, GCUBEScope scope) throws Exception {
if (scopeState != null) {
if (scopeState.containsResource(id)) {
logger.trace("Taking resource " + id + " from the scope state");
scopeState.getResource(id).setScope(scope);
return scopeState.getResource(id);
}
}
if ((id == null) || (id.compareTo("") == 0))
throw new Exception("invalid resource id specified");
if ((type == null) || (type.compareTo("") == 0))
throw new Exception("invalid resource type specified");
ScopedResource sresource = null;
logger.trace("Creating a new resource " + id + "");
if (type.compareToIgnoreCase(GCUBEHostingNode.TYPE) == 0)
sresource = new ScopedGHN(id, scope);
else if (type.compareToIgnoreCase(GCUBERunningInstance.TYPE) == 0)
sresource = new ScopedRunningInstance(id, scope);
else if (type.compareToIgnoreCase(GCUBEService.TYPE) == 0)
sresource = new ScopedDeployedService(id, scope);
else
sresource = new ScopedAnyResource(id, type, scope);
return sresource;
}
/**
* Gets the service that originates the RI, if any
* @param scopedRunningInstance
* @return the service
*/
public static ScopedDeployedService getRelatedService(
ScopedRunningInstance scopedRunningInstance) throws ServiceNotFoundException {
for (ScopedResource resource : scopeState.getResourcesByType(ScopedDeployedService.TYPE)) {
if (resource == null) continue;
try {
ScopedDeployedService service = (ScopedDeployedService)resource;
if ((service.getSourceService().getClazz().compareToIgnoreCase(scopedRunningInstance.getSourceServiceClass())==0)
&& (service.getSourceService().getName().compareToIgnoreCase(scopedRunningInstance.getSourceServiceName())==0)) {
logger.debug("Source service found for RI " + scopedRunningInstance);
return service;
}
}catch (Exception e ) {
logger.warn("An error occurred when looking for the source service for RI "+ scopedRunningInstance + ", error message: " + e.getMessage());
}
}
logger.error("Unable to find a source service for " + scopedRunningInstance);
throw new ServiceNotFoundException();
}
/** Service not found exception, it occurs when a RI was not deployed by this RM instance*/
public static class ServiceNotFoundException extends Exception {
private static final long serialVersionUID = 3904279081090871340L;
}
}

View File

@ -0,0 +1,234 @@
package org.gcube.vremanagement.resourcemanager.impl.resources;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.gcube.common.core.contexts.GCUBERemotePortTypeContext;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.QueryParameter;
import org.gcube.common.core.informationsystem.client.XMLResult;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGHNQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGenericQuery;
import org.gcube.common.core.informationsystem.client.queries.GCUBERIQuery;
import org.gcube.common.core.resources.GCUBEHostingNode;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.vremanagement.ghnmanager.stubs.GHNManagerPortType;
import org.gcube.common.vremanagement.ghnmanager.stubs.ScopeRIParams;
import org.gcube.common.vremanagement.ghnmanager.stubs.service.GHNManagerServiceAddressingLocator;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory.ServiceNotFoundException;
/**
* A scoped {@link GCUBERunningInstance}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class ScopedRunningInstance extends ScopedResource {
public static final String TYPE = GCUBERunningInstance.TYPE;
private String hostingNodeName = "";
/** data of the service from which the RI was generated */
private ServiceData sourceService = new ServiceData();;
/** ghn ID of the node hosting the RI */
private String hostedOnID = "";
/** Scopes the instance belongs to */
private List<String> scopes;
private transient EndpointReferenceType ghnEpr;
protected ScopedRunningInstance(String id, GCUBEScope scope, String ... hostedOn) {
super(id, TYPE, scope);
if ((hostedOn != null) && (hostedOn.length > 0))
this.hostedOn = hostedOn[0];
}
@Override
protected void find() throws Exception {
//looks for the RI to manage
try {
ISClient client = GHNContext.getImplementation(ISClient.class);
//we cannot use here the GCUBERunningInstanceQuery because it returns only ready instances,
//we need to find a RI, no matter in which state it is
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
query.addParameters(new QueryParameter("FILTER", "$result/ID/text()/string() eq \""+id+"\""),
new QueryParameter ("RESULT", "$result"));
List<XMLResult> results = client.execute(query, ServiceContext.getContext().getScope());
//query.addAtomicConditions(new AtomicCondition("/ID/text()", id));
if (results == null || results.size() == 0) {
results = client.execute(query, ServiceContext.getContext().getScope().getEnclosingScope());
if (results == null || results.size() == 0) {
throw new Exception("unable to find target RI "+ this);
}
}
GCUBERunningInstance profile = GHNContext.getImplementation(GCUBERunningInstance.class);
profile.load(new StringReader(results.get(0).evaluate("/").get(0)));
this.sourceService = new ServiceData();
this.sourceService.serviceID = profile.getServiceID();
this.sourceService.serviceClass = profile.getServiceClass();
this.sourceService.serviceName = profile.getServiceName();
this.hostedOnID = profile.getGHNID();
this.scopes = new ArrayList<String>();
for (GCUBEScope scope : profile.getScopes().values())
this.scopes.add(scope.getName());
} catch (Exception e) {
throw new Exception("unable to find the target RI " + this,e);
}
//looks for the GHN to contact
try {
ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEGHNQuery query = client.getQuery(GCUBEGHNQuery.class);
query.addAtomicConditions(new AtomicCondition("/ID/text()", this.hostedOnID));
List<GCUBEHostingNode> hostingNode = client.execute(query, ServiceContext.getContext().getScope());
this.hostingNodeName = hostingNode.get(0).getNodeDescription().getName();
this.ghnEpr = this.loadGHNmanager(hostingNode.get(0).getID(), client);
this.hostedOn = hostingNodeName;
} catch (Exception e) {
this.noHopeForMe("unable to find the hosting GHN (ID=" + this.hostedOnID + ")", new ResourceNotFound(e));
}
}
/**
* Adds the RI to the scope
*
* @throws Exception if it is not possible to add the resource
*/
@Override
protected void addToScope() throws ResourceNotFound, Exception {
if (this.hostingNodeName.compareToIgnoreCase("") == 0)
this.findResource();
try {
GHNManagerServiceAddressingLocator locator = new GHNManagerServiceAddressingLocator();
GHNManagerPortType pt = GCUBERemotePortTypeContext.getProxy(locator.getGHNManagerPortTypePort(this.ghnEpr),
ServiceContext.getContext().getScope(), ServiceContext.getContext());
ScopeRIParams params = new ScopeRIParams();
params.setClazz(this.sourceService.serviceClass);
params.setName(this.sourceService.serviceName);
params.setScope(this.scope);
pt.addRIToScope(params);
} catch (Exception e) {
this.setStatus(STATUS.LOST);
this.success = false;
this.setErrorMessage("Failed to add RunningInstance to scope " + scope);
getLogger().error("Failed to add RunningInstance to scope " + scope, e);
throw new Exception("Failed to add RunningInstance to scope " + scope);
}
}
/**
* Removes the RI from the scope
*
* @throws Exception if it is not possible to remove the resource
*/
@Override
protected void removeFromScope() throws ResourceNotFound,ServiceNotFoundException, Exception {
this.findResource();
try {
GHNManagerServiceAddressingLocator locator = new GHNManagerServiceAddressingLocator();
GHNManagerPortType pt = GCUBERemotePortTypeContext.getProxy(locator.getGHNManagerPortTypePort(this.ghnEpr),
ServiceContext.getContext().getScope(), ServiceContext.getContext());
ScopeRIParams params = new ScopeRIParams();
params.setClazz(this.sourceService.serviceClass);
params.setName(this.sourceService.serviceName);
params.setScope(this.scope);
pt.removeRIFromScope(params);
} catch (Exception e) {
this.noHopeForMe("Failed to remove RunningInstance from scope " + scope.toString() +" "+ e.getMessage(),e);
}
}
protected String getSourceServiceClass() {
return this.sourceService.serviceClass;
}
protected String getSourceServiceName() {
return this.sourceService.serviceName;
}
public boolean isUndeployNeeded() throws ResourceNotFound {
try {
this.findResource();
} catch (ResourceNotFound e) {
this.noHopeForMe("Failed to remove RunningInstance from scope " + scope.toString() +". Can't find the related service to undeploy "+ e.getMessage(),e);
}
if (this.scopes.size() == 1) {
getLogger().info(this + " joins only this scope: it's going to be undeployed");
return true;
}
return false;
}
/**
* @return the ID of the gHN hosting the instance
*/
public String getHostedOnID() {
return hostedOnID;
}
public void reportFailureOnSourceService(String message, Exception e) {
try {
this.noHopeForMe(message, e);
} catch (Exception e1) {
getLogger().error(this + "An error has been reported from outside when managing the source service", e1);
}
}
public void wasSuccessful() {
this.success = true;
}
/**
* Number of times the resource is searched in the IS before to declare it lost
* @return the number of attempts to do
*/
@Override
protected int getMaxFindAttempts(){
return 40;
}
/**
* Looks for the GHN manager's endpoint to contact
* @param id the identifier of the gHN
* @param client the ISClient instance to use
* @return the endpoint reference of gHNManager's portType to contact
* @throws Exception if the search fails
*/
private EndpointReferenceType loadGHNmanager(String id, ISClient client) throws Exception {
//looks for the GHN manager's endpoint to contact
GCUBERIQuery riquery = client.getQuery(GCUBERIQuery.class);
riquery.addAtomicConditions(new AtomicCondition("//GHN/@UniqueID", id),
new AtomicCondition("//ServiceClass", "VREManagement"),
new AtomicCondition("//ServiceName", "GHNManager"));
List<GCUBERunningInstance> results = client.execute(riquery,ServiceContext.getContext().getScope());
return results.get(0).getAccessPoint().getEndpoint("gcube/common/vremanagement/GHNManager");
}
/**
*
* Groups some service data
*
* @author Manuele Simi (ISTI-CNR)
*
*/
class ServiceData {
String serviceID;
String serviceName;
String serviceClass;
}
}

View File

@ -0,0 +1,259 @@
package org.gcube.vremanagement.resourcemanager.impl.resources.types;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
* A thread-safe Map with multiple keys allowing multiple values per key
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class MultiKeysMap<K1, K2, V> implements Iterable<V> {
private List<V> values = Collections.synchronizedList(new LinkedList<V>());
private List<WrappedValue> wrappedValues = Collections.synchronizedList(new LinkedList<WrappedValue>());
private Map<K1, HashSet<V>> k1values = Collections.synchronizedMap(new HashMap<K1, HashSet<V>>());
private Map<K2, HashSet<V>> k2values = Collections.synchronizedMap(new HashMap<K2, HashSet<V>>());
/**
* {@inheritDoc}
*/
public Iterator<V> iterator() {
return values.iterator();
}
/**
* Associates the specified value with the two keys
*
* @param key1 the value's primary key
* @param key2 the value's secondary key
* @param value the value
*/
public void put(K1 key1, K2 key2, V value) {
WrappedValue wrappedValue = this.new WrappedValue(value);
wrappedValue.addKey1(key1);
wrappedValue.addKey2(key2);
if (wrappedValues.contains(wrappedValue))
wrappedValues.remove(wrappedValue);
wrappedValues.add(wrappedValue);
if (values.contains(value))
values.remove(value);
values.add(value);
//add the value index to k1values
if (!k1values.containsKey(key1))
k1values.put(key1, new HashSet<V>());
k1values.get(key1).add(value);
//add the value index to k2values
if (!k2values.containsKey(key2))
k2values.put(key2, new HashSet<V>());
k2values.get(key2).add(value);
}
/**
* removes the given values and its keys from the map
* @param value
*/
public void removeValue(V value) {
values.remove(value);
WrappedValue wvalue = wrappedValues.get(this.wrappedIndexOf(value));
k1values.get(wvalue.key1).remove(value);
if (k1values.get(wvalue.key1).isEmpty())
k1values.remove(wvalue.key1);
k2values.get(wvalue.key2).remove(value);
if (k2values.get(wvalue.key2).isEmpty())
k2values.remove(wvalue.key2);
wrappedValues.remove(wvalue);
}
/**
* Removes all the values associated to the primary key
*
* @param key the key of type K1
*/
public void removeValuesByPrimaryKey(K1 key) {
Set<V> valuesToRemove = k1values.get(key);
if (valuesToRemove == null)
return;
Iterator<V> iterator = valuesToRemove.iterator();
while (iterator.hasNext()) {
V value = iterator.next();
values.remove(value);
if (value == null) {
continue;
}
WrappedValue wvalue = wrappedValues.get(this.wrappedIndexOf(value));
k2values.get(wvalue.key2).remove(value);
if (k2values.get(wvalue.key2).isEmpty())
k2values.remove(wvalue.key2);
wrappedValues.remove(wvalue);
}
k1values.remove(key);
}
/**
* Removes all the values associated to the secondary key
*
* @param key the key of type K2
*/
public void removeValuesBySecondaryKey(K2 key) {
Set<V> valuesToRemove = k2values.get(key);
if (valuesToRemove == null)
return;
Iterator<V> iterator = valuesToRemove.iterator();
while (iterator.hasNext()) {
V value = iterator.next();
values.remove(value);
if (value == null) {
return;
}
WrappedValue wvalue = wrappedValues.get(this.wrappedIndexOf(value));
k1values.get(wvalue.key1).remove(value);
if (k1values.get(wvalue.key1).isEmpty())
k1values.remove(wvalue.key1);
wrappedValues.remove(wvalue);
}
k2values.remove(key);
}
private int wrappedIndexOf(V value) {
int index = 0;
if (value==null)
return -1;
for (WrappedValue wvalue : wrappedValues) {
if (wvalue.equals(value))
return index;
index++;
}
return -1;
}
/**
* Returns the values to which this map maps the specified primary key
*
* @param key key whose associated values are to be returned
* @return the values to which this map maps the specified primary key
*/
@SuppressWarnings("unchecked")
public Set<V> getValuesByPrimaryKey(K1 key) {
return k1values.get(key) == null? (Set<V>)Collections.emptySet(): k1values.get(key);
}
/**
* Returns the values to which this map maps the specified primary key
* @param key key whose associated values are to be returned
* @return @return the values to which this map maps the specified secondary key
*/
@SuppressWarnings("unchecked")
public Set<V> getValuesBySecondaryKey(K2 key) {
return k2values.get(key) == null? (Set<V>)Collections.emptySet(): k2values.get(key);
}
/**
* Returns a set view of the primary keys contained in this map
*
* @return a set view of the primary keys contained in this map
*/
@SuppressWarnings("unchecked")
public Set<K1> primaryKeySet() {
return k1values.keySet() == null? (Set<K1>)Collections.emptySet(): k1values.keySet();
}
/**
* Returns a set view of the secondary keys contained in this map
*
* @return a set view of the secondary keys contained in this map
*/
@SuppressWarnings("unchecked")
public Set<K2> secondaryKeySet() {
return k2values.keySet() == null? (Set<K2>)Collections.emptySet(): k2values.keySet();
}
/**
* Returns a collection view of the values contained in this map
*
* @return a collection view of the values contained in this map
*/
public Collection<V> values() {
return Collections.unmodifiableCollection(values);
}
/**
* Removes all mapping from this maps
*/
public void clean () {
values.clear();
wrappedValues.clear();
k1values.clear();
k2values.clear();
}
/**
*
* Internal Map object
*
* It maps a value V to both its primary and secondary key
*
* @author Manuele Simi (ISTI-CNR)
*
*/
class WrappedValue {
V value;
K1 key1;
K2 key2;
WrappedValue(V value) { this.value = value;}
void addKey1(K1 key) {this.key1=key;}
void addKey2(K2 key) {this.key2=key;}
@Override
public int hashCode() {
return ((value == null) ? 0 : value.hashCode());
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() == obj.getClass()) {
WrappedValue other = (WrappedValue) obj;
if ((this.value == null) && (other.value == null)) {
return true;
} else if (this.value.equals(other.value)) {
return true;
}
} else { //check if obj is the wrapped object
if (this.value.equals(obj)) {
return true;
}
}
return false;
}
}
}

View File

@ -0,0 +1,173 @@
package org.gcube.vremanagement.resourcemanager.impl.state;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.state.GCUBEWSResource;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNodeManager;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory;
import org.gcube.vremanagement.resourcemanager.impl.state.observers.Executor;
import org.gcube.vremanagement.resourcemanager.impl.state.observers.Publisher;
import org.gcube.vremanagement.resourcemanager.impl.state.observers.Serializer;
import org.globus.wsrf.NoSuchResourceException;
/**
* The ResourceManager's stateful resource
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class InstanceState extends GCUBEWSResource {
final protected GCUBEScope scope = ServiceContext.getContext().getInstance().getScopes().values().iterator().next();
protected ScopeState scopeState;
/** session id -> session map*/
static Map<String, Session> id2session = Collections.synchronizedMap(new HashMap<String, Session>());;
@SuppressWarnings("unchecked")
@Override
protected void initialise(Object... params) throws Exception {
scopeState = new ScopeState();
try {
logger.info("Initializing the instance state from the local file system...");
Serializer.load(scopeState, scope);
//synch IS list w/ scopeState
this.getPublishedScopeResource().loadFromLocalState(scopeState); //it's already done by the Publisher observer?
} catch (IOException io) {
logger.warn("The local serialized scope state is not available");
logger.info("Loading the instance state from the IS...");
if (this.getPublishedScopeResource().load()) {
logger.info("Instance state harvested from the IS");
scopeState.initialize(scope, scope.getName(), GHNContext.getContext().isSecurityEnabled());
//synch scopeState w/ IS list
this.getPublishedScopeResource().to(scopeState);
} else {
logger.info("Empty instance state created");
//we assume that if we are running on a secure ghn, we are in a secure Scope
scopeState.initialize(scope, scope.getName(), GHNContext.getContext().isSecurityEnabled());
this.getPublishedScopeResource().loadFromLocalState(scopeState);
}
scopeState.getRawScopeState().data.put("NODES", new HashMap<String, VirtualNode>());
}
ScopedResourceFactory.setResourceList(scopeState);
VirtualNodeManager.setNodes((Map<String, VirtualNode>) scopeState.getRawScopeState().data.get("NODES"));
this.registerObservers();
//let's notify the observers about the current scope state
new Thread() {
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
scopeState.notifyObservers();
}
}.start();
}
private void registerObservers() {
//register the observers
scopeState.addObserver(new Executor());
scopeState.addObserver(new Publisher());
scopeState.addObserver(new Serializer());
}
/**
* Gets the RP <em>ManagedScope</em>
*
* @return the scope managed by this instance
*/
synchronized public GCUBEScope getManagedScope () {
return this.scope;
}
/**
* Gets the {@link Session}
*
* @param id the session ID
* @return the session
* @throws IOException
*/
public Session getSession(String id) throws IOException {
if (! id2session.containsKey(id))
id2session.put(id, Session.load(id));
return id2session.get(id);
}
/**
* Gets the string representation of a {@link Session}
*
* @param id the session ID
* @return the string representation of the session
* @throws IOException
*/
public String getSerializedSession(String id) throws IOException {
return Session.loadAsString(id);
}
/**
* Adds a new {@link Session} to the service's state
*
* @param session the session to add
*/
public void addSession(Session session) {
this.getResourceList().setLastSession(session);
id2session.put(session.getId(), session);
}
/**
* Gets the {@link PublishedScopeResource}
*
* @return the {@link PublishedScopeResource}
* @throws NoSuchResourceException
*/
public PublishedScopeResource getPublishedScopeResource() throws NoSuchResourceException {
try {
return PublishedScopeResource.getResource(this.scope);
} catch (Exception e) {
logger.warn("Unable to get the PublishedScopeResource", e);
throw new NoSuchResourceException();
}
}
/**
* Gets the list of {@link ScopedResource}s
* @return the list of scoped resources
*/
public ScopeState getResourceList() {
return scopeState;
}
/**
* Disposes the current scope
*/
public void dispose() {
Set<ScopedResource> allResources = new HashSet<ScopedResource>();
for (ScopedResource resource : this.scopeState.getAllResources()) {
allResources.add(resource);
}
//remove all resources
this.scopeState.removeResources(allResources);
//TODO: unpublish the published scope resource
//TODO: undeploy myself?
}
}

View File

@ -0,0 +1,56 @@
package org.gcube.vremanagement.resourcemanager.impl.state;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;
/**
* Transforms from {@link Date} to a valid string representation for the <em>xs:dateAndTime</em> XML Schema data type and vice versa.
* It can be used to write/read a {@link Date} object to/from a profile.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public final class ProfileDate {
static final DateFormat dateAndTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
/**
* Transforms the input {@link Date} in a valid string representation for the <em>xs:dateAndTime</em> XML Schema data type
* @param date the {@link Date} object to tranform
* @return the {@link String} object
*/
public static synchronized String toXMLDateAndTime(Date date) {
String formatted = dateAndTime.format(date);
StringBuilder toXS = new StringBuilder();
toXS.append(formatted.substring(0, formatted.length()-2));
toXS.append(":");
toXS.append(formatted.substring(formatted.length()-2, formatted.length()));
return toXS.toString();
}
/**
* Transforms the input <em>xs:dateAndTime</em> representation in a {@link Date} object
* @param date the string representation of <em>xs:dateAndTime</em> (e.g. &quot 2009-05-12T16:46:03+02:00 &quot)
* @return the {@link Date} object
* @throws ParseException if the input date is not in an valid format
*/
public static synchronized Date fromXMLDateAndTime(String date) throws ParseException {
//the test is for backward compatibility, to read the old profiles that have no time zone in the dateAndTime fields
Pattern p = Pattern.compile("^.*T\\d{2}:\\d{2}:\\d{2}$"); //ends with 'T'HH:mm:ss
if (p.matcher(date).matches()) {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(date);
} else {
StringBuilder toDate = new StringBuilder();
toDate.append(date.substring(0, date.length()-3));
toDate.append(date.substring(date.length()-2, date.length()));
return dateAndTime.parse(toDate.toString());
}
}
}

View File

@ -0,0 +1,622 @@
package org.gcube.vremanagement.resourcemanager.impl.state;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STATUS;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGenericResourceQuery;
import org.gcube.common.core.informationsystem.publisher.ISPublisher;
import org.gcube.common.core.resources.GCUBEGenericResource;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.scope.GCUBEScope.Type;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.kxml2.io.KXmlParser;
import org.kxml2.io.KXmlSerializer;
/**
* The scope resource published in the IS
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class PublishedScopeResource {
protected GCUBELog logger = new GCUBELog(this);
private GCUBEGenericResource resource;
private PublishedResourceList publishedResourceList;
private GCUBEScope scope;
private static final String NS ="";
private String creator = "", designer = "", service = "";
private Date startTime = null, endTime = null;
private boolean securityEnabled = false;
private boolean loaded = false;
private boolean dismissed =false;
private static Map<GCUBEScope,PublishedScopeResource> cache = new HashMap<GCUBEScope, PublishedScopeResource>();;
public void reload() throws Exception {
try {
publishedResourceList = new PublishedResourceList();
this.load();
//this.store();//to make sure we have locally the latest resource
} catch (Exception e) {
logger.error("Failed to reload the Scope Resource");
throw e;
}
}
// make it private to avoid explicit creation of VREscope objects
private PublishedScopeResource(GCUBEScope scope) throws Exception{
this.scope = scope;
publishedResourceList = new PublishedResourceList();
//get the service EPR from the RI profile
this.service = ServiceContext.getContext().getInstance().getAccessPoint().getRunningInstanceInterfaces().getEndpoint().get(0).getValue();
// get the resource implementation
try {
this.resource = GHNContext.getImplementation(GCUBEGenericResource.class);
} catch (Exception e) {
throw new Exception("Unable to create resource to publish for " + scope.toString());
}
}
/**
* Gets the current Scope Resource
* @param scope the scope of the resource to load
* @return the PublishedScopeResource
*/
public static PublishedScopeResource getResource(GCUBEScope scope) throws Exception {
if (! cache.containsKey(scope))
cache.put(scope, new PublishedScopeResource(scope));
return cache.get(scope);
}
/**
* Adds a resource to PublishedScopeResource
*
* @param resource
* @throws Exception
*/
public void addResource(ScopedResource resource) throws Exception {
this.publishedResourceList.add(resource.getId(), resource.getType(),resource.getJointTime(), resource.getHostedOn());
resource.setStatus(STATUS.PUBLISHED);
}
/**
* Removes a resource from the PublishedScopeResource
*
* @param resource
* @throws Exception
*/
public void removeResource(ScopedResource resource) throws Exception {
this.publishedResourceList.remove(resource.getId(), resource.getType());
resource.setStatus(STATUS.UNPUBLISHED);
}
/**
* Returns a string representation of the PublishedScopeResource
* @throws IOException
*/
public String toString() {
try {
this.resource.setBody(this.prepareBody());
StringWriter ret = new StringWriter();
this.resource.store(ret);
return ret.toString();
} catch (Exception e) { logger.error("Invalid Scope Resource serialization",e); return "";}
}
/**
* @return the scope
*/
public GCUBEScope getScope() {
return scope;
}
/**
* Returns the type of the scope.
*
* @return the type.
*/
public Type getType() {
return scope.getType();
}
/**
* Sets a scope option
*
* @param name
* the option name
* @param value
* the option value
* @throws Exception
* @throws ParseException
*/
public void setOption(String name, String value)
throws Exception {
if (value == null)
return;
try {
if (name.compareToIgnoreCase("DESIGNER") == 0) {
// the designer's DN
this.designer = value;
} else if (name.compareToIgnoreCase("CREATOR") == 0) {
// the creator's DN
this.creator = value;
} else if (name.compareToIgnoreCase("ENDTIME") == 0) {
// the time at which the scope will be dismissed
this.endTime = ProfileDate.fromXMLDateAndTime(value);
} else if (name.compareToIgnoreCase("STARTTIME") == 0) {
// the time this scope was created
this.startTime = ProfileDate.fromXMLDateAndTime(value);
} else if (name.compareToIgnoreCase("DESCRIPTION") == 0) {
// the scope description
this.resource.setDescription(value);
} else if (name.compareToIgnoreCase("DISPLAYNAME") == 0) {
// the name to display (the unique name is the qualified scope)
this.resource.setName(value);
} else if (name.compareToIgnoreCase("SECURITYENABLED") == 0) {
// the name to display (the unique name is the qualified scope)
this.securityEnabled = Boolean.valueOf(value);
} else
throw new UnknownScopeOptionException();
} catch (ParseException e) {
throw new Exception ("Unable to parse option " + name);
}
}
/**
* Publishes the {@link PublishedScopeResource} into the IS
*/
public synchronized void publish() throws Exception {
if (this.dismissed) return;
this.resource.setBody(this.prepareBody());
logger.trace("Publishing Scope Resource: \n" + this.toString());
//this.store();
ISPublisher publisher = GHNContext.getImplementation(ISPublisher.class);
if (this.loaded) {
publisher.updateGCUBEResource(this.resource, this.scope, ServiceContext.getContext());
}
else {
publisher.registerGCUBEResource(this.resource, this.scope, ServiceContext.getContext());
this.loaded = true;
}
}
/**
* Dismisses the {@link PublishedScopeResource} from the IS and the scope
*/
public synchronized void dismiss() throws Exception {
this.resource.setBody(this.prepareBody());
logger.trace("Unpublishing Scope Resource: \n" + this.toString());
//this.store();
ISPublisher publisher = GHNContext.getImplementation(ISPublisher.class);
publisher.removeGCUBEResource(this.resource.getID(), this.resource.getType(), this.scope, ServiceContext.getContext());
this.dismissed = true;
}
private String prepareBody() throws IOException {
StringWriter body = new StringWriter(); // serialises to a temporary writer first
KXmlSerializer serializer = new KXmlSerializer();
serializer.setOutput(body);
try {
serializer.startDocument("UTF-8", true);
serializer.startTag(NS,"Scope").text(scope.toString()).endTag(NS,"Scope");
serializer.startTag(NS,"Service").text(this.service).endTag(NS,"Service");
serializer.startTag(NS,"Creator").text(this.getCreator()).endTag(NS,"Creator");
serializer.startTag(NS,"Designer").text(this.getDesigner()).endTag(NS,"Designer");
if (this.startTime == null)
this.startTime = Calendar.getInstance().getTime();
serializer.startTag(NS,"StartTime").text(ProfileDate.toXMLDateAndTime(this.startTime)).endTag(NS,"StartTime");
if (this.endTime != null)
serializer.startTag(NS,"EndTime").text(ProfileDate.toXMLDateAndTime(this.endTime)).endTag(NS,"EndTime");
serializer.startTag(NS,"SecurityEnabled").text(String.valueOf(this.securityEnabled)).endTag(NS,"SecurityEnabled");
publishedResourceList.store(serializer);
} catch (Exception e) {
logger.error("The Scope Resource does not have a valid serialisation", e);
throw new IOException("The Scope Resource does not have a valid serialisation");
}
finally {
body.close();
}
return body.toString();
}
/**
* @return the creator
*/
public String getCreator() {
return (creator != null) ? creator : "";
}
/**
* @return the designer
*/
public String getDesigner() {
return (designer != null)? designer : "";
}
/**
* @return the description
*/
public String getDescription() {
return (this.resource.getDescription() != null)? this.resource.getDescription() : "";
}
/**
* @return the display name
*/
public String getDisplayName() {
return (this.resource.getName() != null) ? this.resource.getName() : "";
}
/**
* @return the startTime
*/
public Date getStartTime() {
return startTime;
}
/**
* @return the endTime
*/
public Date getEndTime() {
return endTime;
}
/**
* @return the securityEnabled
*/
public boolean isSecurityEnabled() {
return securityEnabled;
}
/**
* Loads from the <em>Body</em> element the resource information
* @param body the <em>Body</em> of the generic resource
* @throws Exception if the element is not valid or well formed
*/
private void parseBody(String body) throws Exception {
KXmlParser parser = new KXmlParser();
parser.setInput(new BufferedReader(new StringReader(body)));
loop: while (true) {
try {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("Creator")) this.creator = parser.nextText();
else if (parser.getName().equals("Designer")) this.designer = parser.nextText();
else if (parser.getName().equals("EndTime")) this.endTime = ProfileDate.fromXMLDateAndTime(parser.nextText());
else if (parser.getName().equals("StartTime")) this.startTime = ProfileDate.fromXMLDateAndTime(parser.nextText());
//else if (parser.getName().equals("DisplayName")) this.display = parser.nextText();
else if (parser.getName().equals("SecurityEnabled")) this.securityEnabled = Boolean.valueOf(parser.nextText());
else if (parser.getName().equals(PublishedResourceList.RESOURCES_ELEMENT)) publishedResourceList.load(parser);
else parser.nextText();//just skip the text
break;
case KXmlParser.END_DOCUMENT: break loop;
}
} catch (Exception e) {
throw new Exception ("Unable to parse the PublishedScopeResource body");
}
}
}
/**
* Loads the scope resource from the IS
* @param resource the resource to load
*
* @return true if the resource is successfully loaded, false otherwise
*/
protected boolean load() {
try {
ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEGenericResourceQuery query = client.getQuery(GCUBEGenericResourceQuery.class);
query.addAtomicConditions(new AtomicCondition("//SecondaryType", determineSecondaryType()),
new AtomicCondition("//Body/Scope", scope.toString()));
//logger.trace(query.toString());
List<GCUBEGenericResource> results = client.execute(query, scope);
if ((results != null) && (results.size() > 0)) {
this.resource = results.get(0);
this.parseBody(this.resource.getBody());
this.loaded = true;
logger.trace("Resource loaded from the IS: \n" + this.toString());
return true;
} else
logger.warn("Unable to load the resource for "+ this.scope.toString() + " from the IS");
} catch (Exception e) {logger.warn("Published resource for "+ this.scope.toString()+ " does not exist on the IS yet", e);}
return false;
}
/**
* Determines the secondary type of the scope resource
*
* @return the secondary type
*/
private String determineSecondaryType() {
if (this.scope.getType() == Type.VRE)
return GCUBEGenericResource.SECONDARYTYPE_VRE;
else if (this.scope.getType() == Type.VO)
return GCUBEGenericResource.SECONDARYTYPE_VO;
else
return GCUBEGenericResource.SECONDARYTYPE_INFRASTRUCTURE;
}
public boolean loaded() {
return this.loaded;
}
/**
* Fills the input {@link ScopeState} with the actual content of the {@link PublishedResourceList}
*
* @param scopeState the list to fill
*/
public void to(ScopeState scopeState) {
logger.debug("To: Filling the local scope state with the published state");
scopeState.addResources(publishedResourceList.asScopedResouces());
scopeState.setDesigner(this.getDesigner());
scopeState.setManager(this.getCreator());
scopeState.setSecurity(this.isSecurityEnabled());
scopeState.changeDescription(this.getDescription());
scopeState.setEndTime(this.endTime);
logger.trace("Setting the scope state to " + ProfileDate.toXMLDateAndTime(this.startTime));
scopeState.setStartTime(this.startTime);
logger.trace("Scope state set to:" + ProfileDate.toXMLDateAndTime(scopeState.getStartTime()));
scopeState.setName(this.getDisplayName());
}
/**
* Fills this {@link PublishedResourceList} with the content of the input {@link ScopeState}
*
* @param scopeState the list to load
* @throws Exception if the load fails
*/
public synchronized void loadFromLocalState(ScopeState scopeState) throws Exception {
logger.debug("LoadFromLocalState: Loading the published state from the local scope state");
//reloading is needed in order to reuse the resource ID and
//to avoid to cancel the old Generic Resource from the IS (plus reusing any other information do not overridden)
this.reload();
publishedResourceList = new PublishedResourceList();//empty the scopeState
this.synchBasicInfo(scopeState);
for(ScopedResource resource : scopeState.getAllResources())
this.addResource(resource);
//initialise some resource's fields
if (this.scope.getType() == Type.VRE)
this.resource.setSecondaryType(GCUBEGenericResource.SECONDARYTYPE_VRE);
else if (this.scope.getType() == Type.VO)
this.resource.setSecondaryType("VO");
else
this.resource.setSecondaryType("INFRASTRUCTURE");
this.resource.addScope(this.scope);
// force the first serialization of Body
this.toString();
}
/**
* Synchronizes this {@link PublishedResourceList} with the content of the input {@link ScopeState}
*
* @param scopeState the list to synchronize with
* @throws Exception if the synchronization fails
*/
public synchronized void synchWithLocalState(ScopeState scopeState) throws Exception {
logger.debug("SynchWithLocalState: Synch the published state from the scope state");
for(ScopedResource resource : scopeState.getAllResources()) {
switch (resource.getStatus()) {
case ADDED: this.addResource(resource); break;
case REMOVED: this.removeResource(resource); break;
case LOST: this.removeResource(resource); break;
//in the other statuses, the resource is just ignored
}
}
this.synchBasicInfo(scopeState);
}
private void synchBasicInfo(ScopeState scopeState) throws Exception {
logger.debug("Synchronizing basic info to publish");
this.setOption("CREATOR",scopeState.getManager());
this.setOption("DESIGNER",scopeState.getDesigner());
this.setOption("DESCRIPTION",scopeState.getDescription());
this.setOption("DISPLAYNAME",scopeState.getName());
//here we directly assign the values, don't want to format/unformat them via setOption()
this.endTime = scopeState.getEndTime();
this.startTime = scopeState.getStartTime();
this.securityEnabled = scopeState.isSecurityEnabled();
}
/** InvalidVREOption exception */
public static class UnknownScopeOptionException extends Exception {
private static final long serialVersionUID = 1L;
}
/**
* List of resources forming the {@link PublishedScopeResource}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
class PublishedResourceList {
private Set<Item> resources = Collections.synchronizedSet(new HashSet<Item>());
private static final String RESOURCES_ELEMENT = "ScopedRescources";
private static final String RESOURCE_ELEMENT = "ScopedRescource";
class Item {
protected String id;
protected String type;
protected String hostedOn;
protected Date timestamp;
protected Item(String id, String value, Date timestamp, String ... hostedOn) {
this.id = id;
this.type = value;
this.timestamp = timestamp;
this.hostedOn = (hostedOn!=null && hostedOn.length>0) ? hostedOn[0] : null;
}
protected Item(String id, String value, String ... hostedOn) {
this(id, value, null, hostedOn);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result
+ ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Item other = (Item) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
}
void add(String id, String type, Date time, String ... hostedOn) {resources.add(new Item(id, type, time, hostedOn));}
void remove(String id, String type) {resources.remove(new Item(id, type)); }
Set<ScopedResource> asScopedResouces() {
Set<ScopedResource> temp = new HashSet<ScopedResource>();
for (Item item : resources) {
ScopedResource resource;
try {
resource = ScopedResourceFactory.newResource(item.id, item.type, scope);
resource.setJointTime(item.timestamp);
if ((item.hostedOn != null) && (item.hostedOn.compareTo("") != 0))
resource.setHostedON(item.hostedOn);
temp.add(resource);
} catch (Exception e) {
logger.error("Can't build the resource",e);
}
}
return temp;
}
int getSize() {return resources.size();}
/**
* Stores the resources in the given serializer
* @param serializer the serializer
* @throws IOException if the storage fails
*/
void store(KXmlSerializer serializer) throws IOException {
serializer.startTag(PublishedScopeResource.NS, RESOURCES_ELEMENT);
for (Item item : resources) {
serializer.startTag(PublishedScopeResource.NS, RESOURCE_ELEMENT);
serializer.startTag(PublishedScopeResource.NS, "ResourceID").text(item.id).endTag(PublishedScopeResource.NS, "ResourceID");
serializer.startTag(PublishedScopeResource.NS, "ResourceType").text(item.type).endTag(PublishedScopeResource.NS, "ResourceType");
if ((item.hostedOn != null) && (item.hostedOn.compareTo("") != 0))
serializer.startTag(PublishedScopeResource.NS, "HostedOn").text(item.hostedOn).endTag(PublishedScopeResource.NS, "HostedOn");
if (item.timestamp != null)
serializer.startTag(PublishedScopeResource.NS, "JointTime").text(ProfileDate.toXMLDateAndTime(item.timestamp)).endTag(PublishedScopeResource.NS, "JointTime");
serializer.endTag(PublishedScopeResource.NS, RESOURCE_ELEMENT);
}
serializer.endTag(PublishedScopeResource.NS, RESOURCES_ELEMENT);
}
/**
* Parses the <em>Resources</em> element
* @param parser the parser
* @throws Exception if the element is not valid or well formed
*/
void load(KXmlParser parser) throws Exception {
loop: while (true) {
try {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals(RESOURCE_ELEMENT)) {
String id=null, type=null, hostedOn=null;
Date time = null;
innerloop: while (true) {
switch (parser.next()) {
case KXmlParser.START_TAG:
if (parser.getName().equals("ResourceID")) id=parser.nextText();
else if (parser.getName().equals("ResourceType")) type=parser.nextText();
else if (parser.getName().equals("HostedOn")) hostedOn=parser.nextText();
else if (parser.getName().equals("JointTime")) time=ProfileDate.fromXMLDateAndTime(parser.nextText());
else parser.nextText();
break;
case KXmlParser.END_TAG: if (parser.getName().equals(RESOURCE_ELEMENT)){this.add(id, type, time, hostedOn);break innerloop;}
break;
case KXmlParser.END_DOCUMENT: throw new Exception ("Parsing failed at " + RESOURCE_ELEMENT);
}
}
}
break;
case KXmlParser.END_TAG: if (parser.getName().equals(RESOURCES_ELEMENT)) break loop;
break;
case KXmlParser.END_DOCUMENT: throw new Exception ("Failed to parse at " + RESOURCES_ELEMENT);
}
} catch (Exception e) {
throw new Exception ("Failed to parse at Resources");
}
}
}
}
}

View File

@ -0,0 +1,55 @@
package org.gcube.vremanagement.resourcemanager.impl.state;
import java.util.HashMap;
import java.util.Map;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.types.MultiKeysMap;
/**
*
* The scope state.
*
* While {@link ScopeState} incorporates the behavior of a scope state, this separate and
* minimal class contains only the core information to serialize and nothing else.
* This way, the serialized data are separated from the state behavior, by minimizing
* the need of future changes in the state class.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class RawScopeState {
/** the scope this state belongs to*/
protected String scope;
/** the list of resources */
protected MultiKeysMap<String, String, ScopedResource> resources;
//Open structure for information to store. By using it, we will avoid to broke XSTREAM serialization
//when we need to add more information to the class
/** any data belonging the state worthy to be serialized*/
protected Map<String, Object> data;
protected RawScopeState () {}
/**
* Initializes the state
* @param scope the scope this state belongs to
*/
protected void initialize(final GCUBEScope scope) {
resources = new MultiKeysMap<String, String, ScopedResource>();
data = new HashMap<String, Object>();
this.scope = scope.toString();
}
/**
* @return the scope this state belongs to
*/
public GCUBEScope getScope() {
return GCUBEScope.getScope(this.scope);
}
}

View File

@ -0,0 +1,21 @@
package org.gcube.vremanagement.resourcemanager.impl.state;
import org.gcube.common.core.contexts.GCUBEStatefulPortTypeContext;
import org.gcube.common.core.state.GCUBEWSHome;
import org.gcube.vremanagement.resourcemanager.impl.contexts.StatefulPortTypeContext;
/**
*
* Home for stateful resource
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class ResourceManagerHome extends GCUBEWSHome {
@Override
public GCUBEStatefulPortTypeContext getPortTypeContext() {
return StatefulPortTypeContext.getContext();
}
}

View File

@ -0,0 +1,329 @@
package org.gcube.vremanagement.resourcemanager.impl.state;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Observable;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STATUS;
import org.gcube.vremanagement.resourcemanager.impl.state.observers.Serializer;
/**
*
* A list of scoped resources
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class ScopeState extends Observable {
protected GCUBELog logger = new GCUBELog(this);
/** last operation performed on the list*/
protected OPERATION lastOperationPerformed;
public enum OPERATION {CREATED, LOADED, TOBEMANAGED, PUBLISHED, SERIALIZED, EXECUTED};
private RawScopeState rawState;
private Session report;
protected ScopeState() {}
protected void initialize(GCUBEScope scope, String name, boolean securityEnabled, String ... description) {
rawState = new RawScopeState();
rawState.initialize(scope);
this.rawState.data.put("NAME", name);
this.lastOperationPerformed = OPERATION.CREATED;
if (!this.rawState.data.containsKey("STARTTIME"))
this.rawState.data.put("STARTTIME", Calendar.getInstance().getTime());
this.rawState.data.put("ENDTIME", null);
if ((! this.rawState.data.containsKey("DESCRIPTION")) && (description.length > 0))
this.rawState.data.put("DESCRIPTION", description[0]);
this.rawState.data.put("SECURITYENABLED",securityEnabled);
}
/**
* Sets the scope manager identity
* @param manager the manager
*/
public synchronized void setManager(String manager) {
this.rawState.data.put("MANAGER", manager);
this.notifyObservers();
}
/**
* Sets the scope designer identity
* @param manager the manager
*/
public synchronized void setDesigner(String designer) {
this.rawState.data.put("DESIGNER", designer);
this.notifyObservers();
}
/**
* Changes the scope description
*
* @param description the description
*/
public synchronized void changeDescription (String description) {
this.rawState.data.put("DESCRIPTION", description);
this.notifyObservers();
}
/**
* Adds a new resources to the list
* @param newresources the resources to add
*/
public synchronized void addResources(Set<ScopedResource> newresources) {
for (ScopedResource resource : newresources) {
//if (resource.getStatus() != STATUS.PUBLISHED)//no need to manage it again
resource.setStatus(STATUS.ADDREQUESTED);
if (rawState.resources.primaryKeySet().contains(resource.getId()))
rawState.resources.removeValuesByPrimaryKey(resource.getId());
rawState.resources.put(resource.getId(), resource.getType(), resource);
}
this.setLastOperationPerformed(OPERATION.TOBEMANAGED);
this.notifyObservers();
}
/**
* Gets resources of the given type
*
* @param type the type to filter
* @return the collection of resources
*/
public synchronized Set<ScopedResource> getResourcesByType(String type) {
return rawState.resources.getValuesBySecondaryKey(type);
}
/**
* Gets the resource with the given id
*
* @param id the resource identified
* @return the resource
*/
public synchronized ScopedResource getResource(String id) {
return (ScopedResource) rawState.resources.getValuesByPrimaryKey(id).iterator().next();
}
public boolean containsResource(String id) {
return rawState.resources.primaryKeySet().contains(id);
}
/**
* Removes all the resource of the given type
*
* @param type the type of resources to remove
*/
public synchronized void removeAllResourcesByType(String type) {
for (ScopedResource resource : rawState.resources.getValuesBySecondaryKey(type)) {
resource.setStatus(STATUS.REMOVEREQUESTED);
rawState.resources.put(resource.getId(), resource.getType(), resource);//TODO: is needed?
}
this.setLastOperationPerformed(OPERATION.TOBEMANAGED);
this.notifyObservers();
rawState.resources.removeValuesBySecondaryKey(type);
}
/**
* Removes the resources from the scope
*
* @param oldresources the resources to remove
*
*/
public synchronized void removeResources(Set<ScopedResource> oldresources) {
//resources must be in the state in order to be removed :-)
//this is to prevent service's unconscious cleanup..
for (ScopedResource resource : oldresources) {
resource.setStatus(STATUS.REMOVEREQUESTED);
rawState.resources.put(resource.getId(), resource.getType(), resource);
if (resource.getType().compareToIgnoreCase(ScopedDeployedService.TYPE) == 0) {
((ScopedDeployedService) resource).setCallbackID(this.getLastReport().getId());
((ScopedDeployedService) resource).scheduleUndeploy();
}
}
this.setLastOperationPerformed(OPERATION.TOBEMANAGED);
this.notifyObservers(); //let the obs do their work before to remove the resources
for (ScopedResource resource : oldresources) {
logger.debug("Removing resource " + resource+ " from the scope state");
if (resource.getStatus() == STATUS.UNPUBLISHED) {
rawState.resources.removeValuesByPrimaryKey(resource.getId());
logger.debug("...removed");
} else {
logger.warn("Resource " + resource + " is still PUBLISHED in the scope state, can't be removed");
}
}
this.notifyObservers(); //notify about the physical removal(s)
}
/**
* Removes the resource from the state, no matter about its actual status
* @param resources
*/
public synchronized void forceResourceRemoval(Set<ScopedResource> resources) {
for (ScopedResource resource : resources) {
logger.debug("Removing resource " + resources+ " from the scope state");
rawState.resources.removeValuesByPrimaryKey(resource.getId());
}
}
/**
* Empty the list of resources
*/
protected synchronized void removeAllResources() {
for (ScopedResource resource : rawState.resources.values())
resource.setStatus(STATUS.REMOVEREQUESTED);
this.setLastOperationPerformed(OPERATION.TOBEMANAGED);
this.notifyObservers();
rawState.resources.clean();
}
/**
* Gets the resource's scope
*
* @return the scope
*/
public GCUBEScope getScope() {
return rawState.getScope();
}
public synchronized void notifyObservers(Object whatschanged) {
// Otherwise it won't propagate changes
setChanged();
super.notifyObservers(whatschanged);
}
public synchronized void notifyObservers() {
// Otherwise it won't propagate changes
setChanged();
super.notifyObservers();
}
/**
* Gets all the {@link ScopedResource}s
*
* @return all the {@link ScopedResource}s
*/
public synchronized Collection<ScopedResource> getAllResources() {
return Collections.unmodifiableCollection(rawState.resources.values());
}
/**
* Gets the scope manager
* @return the scope manger
*/
public String getManager() {
return (String) this.rawState.data.get("MANAGER");
}
/**
* Gets the scope designer
* @return the scope designer
*/
public String getDesigner() {
return (String) this.rawState.data.get("DESIGNER");
}
public String getDescription() {
return (String) this.rawState.data.get("DESCRIPTION");
}
public String getName() {
return (String) this.rawState.data.get("NAME");
}
public Date getEndTime() {
return (Date) this.rawState.data.get("ENDTIME");
}
public Date getStartTime() {
return (Date) this.rawState.data.get("STARTTIME");
}
public boolean isSecurityEnabled() {
return (Boolean) this.rawState.data.get("SECURITYENABLED");
}
public void setEndTime(Date endTime) {
this.rawState.data.put("ENDTIME", endTime);
this.notifyObservers();
}
public void setStartTime(Date startTime) {
logger.trace("setStartTime: Start time " + ProfileDate.toXMLDateAndTime(startTime));
this.rawState.data.put("STARTTIME", startTime);
this.notifyObservers();
}
public void setName(String name) {
this.rawState.data.put("NAME", name);
this.notifyObservers();
}
/**
* @return the the last operation performed on the list
*/
public OPERATION getLastOperationPerformed() {
return lastOperationPerformed;
}
/**
* @param operation the last operation performed on the list
*/
public synchronized void setLastOperationPerformed(OPERATION operation) {
this.lastOperationPerformed = operation;
}
/**
* Gets the {@link RawScopeState}
* @return the raw state
*/
public RawScopeState getRawScopeState() {
return rawState;
}
/**
* Sets the new {@link RawScopeState}
* it usually invoked at deserialization time, see {@link Serializer#load(ScopeState, GCUBEScope)}
* @param state
*/
public void setRawScopeState(RawScopeState state) {
this.rawState = state;
}
public void setSecurity(boolean securityEnabled) {
this.rawState.data.put("SECURITYENABLED",securityEnabled);
}
/**
* Gets the last active {@link Session}
* @return the session
*/
public Session getLastReport() {
return this.report;
}
/**
* Sets the last active {@link Session}
* @param session the session
*/
public void setLastSession(Session report) {
this.report = report;
}
}

View File

@ -0,0 +1,463 @@
package org.gcube.vremanagement.resourcemanager.impl.state;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.deployment.DeployerReport;
import org.gcube.vremanagement.resourcemanager.impl.deployment.DeployerReport.DeployedRunningInstance;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.Dependency;
import org.gcube.vremanagement.resourcemanager.impl.deployment.resources.DeployedDependency;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STATUS;
import org.kxml2.io.KXmlSerializer;
/**
* Session for each service operation.
* It holds all the information related to the activities performed to
* satisfy the caller's request.
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class Session implements Serializable {
protected final GCUBELog logger = new GCUBELog(this, ServiceContext.getContext());
final static String NS = "";
/** */
private static final long serialVersionUID = 1180822699138069365L;
private static final String reportDir = "reports";
/** report last update timestamp */
private Calendar lastUpdate = new GregorianCalendar();
private String id = "";
private OPERATION operation;
private GCUBEScope scope = null;
private boolean brokerWasSuccessful, brokerReportAvailable = false;
private String brokerMessage = "";
/** ghn id -> deployer report map*/
private Map<String, DeployerReport> node2report = Collections.synchronizedMap(new HashMap<String, DeployerReport>());
/** Status of a dependency resolver request */
public enum DEPSTATUS {SUCCESS, FAILED};
public enum OPERATION {Create, AddResources, UpdateResources, RemoveResources, Dispose};
private Set<ScopedDeployedService> services = Collections.synchronizedSet(new HashSet<ScopedDeployedService>());
private Set<ScopedResource> resources = Collections.synchronizedSet(new HashSet<ScopedResource>());
/** the instances deployed by the services included in this report*/
private Set<DeployedRunningInstance> instances = new HashSet<DeployedRunningInstance>();
private String deploymentPlan;
/** internally used by {@link Session#loadAsString(String)}*/
private Session () {}
/**
* Builds a new empty report
* @param id the session ID assigned to the operation
*/
public Session(String id, OPERATION operation, GCUBEScope ... scope) {
this.id = id;
this.operation = operation;
if ((scope == null)|| (scope[0] == null))
this.scope = ServiceContext.getContext().getInstance().getScopes().values().iterator().next();
else
this.scope = scope[0];
}
/**
* Adds a Deployer Report to the Resource Report
* @param report the string representation of the report, as sent by a Deployer service
* @throws Exception if a problem in the report parsing occurs
*/
synchronized public void addGHNReport(DeployerReport report) throws Exception {
node2report.put(report.getGHNID(), report);
this.lastUpdate = new GregorianCalendar();
}
synchronized public void addResource(ScopedResource resource) {
this.resources.add(resource);
this.lastUpdate = new GregorianCalendar();
}
synchronized public void addService(ScopedDeployedService service) {
this.services.add(service);
this.lastUpdate = new GregorianCalendar();
}
/**
*
*/
public String toXML() throws IOException {
StringWriter report = new StringWriter(); // serialises to a temporary writer first
KXmlSerializer serializer = new KXmlSerializer();
serializer.setOutput(report);
//serializer.setProperty(XmlSerializer, "\t");
try {
serializer.startDocument("UTF-8", true);
serializer.startTag(NS,"ResourceReport");
serializer.startTag(NS,"ID").text(this.id).endTag(NS, "ID");
serializer.startTag(NS,"Status").text(this.isReportClosed()?"CLOSED" :"OPEN").endTag(NS, "Status");
serializer.startTag(NS,"Operation").text(this.operation.toString()).endTag(NS, "Operation");
serializer.startTag(NS,"LastUpdate").text(ProfileDate.toXMLDateAndTime(this.lastUpdate.getTime())).endTag(NS,"LastUpdate");
serializer.startTag(NS,"TargetScope").text(this.scope.toString()).endTag(NS,"TargetScope");
//resources section
serializer.startTag(NS,"Resources");
for (ScopedResource resource : resources) {
serializer.startTag(NS,"Resource");
serializer.startTag(NS,"ID").text(resource.getId()).endTag(NS,"ID");
serializer.startTag(NS,"Type").text(resource.getType()).endTag(NS,"Type");
if (resource.isSuccess()) {
if (this.operation == OPERATION.AddResources)
serializer.startTag(NS,"Status").text("ADDED").endTag(NS,"Status");
else
serializer.startTag(NS,"Status").text("REMOVED").endTag(NS,"Status");
//serializer.startTag(NS,"ErrorDescription").text("-").endTag(NS,"ErrorDescription");
} else {
serializer.startTag(NS,"Status").text("FAILED").endTag(NS,"Status");
serializer.startTag(NS,"ErrorDescription").text(resource.getErrorMessage()).endTag(NS,"ErrorDescription");
}
serializer.endTag(NS,"Resource");
}
serializer.endTag(NS,"Resources");
//broker section
if (brokerReportAvailable) {
serializer.startTag(NS,"DeploymentPlanCreation");
serializer.startTag(NS,"Status").text(this.brokerWasSuccessful?"SUCCESS":"FAILED").endTag(NS, "Status");
serializer.startTag(NS,"Message").text(this.brokerMessage).endTag(NS, "Message");
serializer.endTag(NS,"DeploymentPlanCreation");
}
//services
serializer.startTag(NS,"Services");
for (ScopedDeployedService service : this.services) {
serializer.startTag(NS,"Service");
serializer.startTag(NS,"ID").text(service.getId()).endTag(NS, "ID");
serializer.startTag(NS,"Class").text(service.getSourceService().getClazz()).endTag(NS, "Class");
serializer.startTag(NS,"Name").text(service.getSourceService().getName()).endTag(NS, "Name");
serializer.startTag(NS,"Version").text(service.getSourceService().getVersion()).endTag(NS, "Version");
if (((this.operation == OPERATION.AddResources) ||(this.operation == OPERATION.Create))
&& (service.getStatus() != STATUS.LOST) && (this.brokerWasSuccessful)) {
if ( (service.getMissingDependencies(service.getTargetGHNID()).size() > 0) || (service.getErrorMessage().length() > 0) ) {
serializer.startTag(NS,"DependenciesResolutionStatus").text(DEPSTATUS.FAILED.name()).endTag(NS, "DependenciesResolutionStatus");
serializer.startTag(NS,"DeployedOn").text("not deployed").endTag(NS, "DeployedOn");
serializer.startTag(NS,"ErrorDescription").text(service.getErrorMessage()).endTag(NS, "ErrorDescription");
}else {
serializer.startTag(NS,"DependenciesResolutionStatus").text(DEPSTATUS.SUCCESS.name()).endTag(NS, "DependenciesResolutionStatus");
serializer.startTag(NS,"DeployedOn").text(service.getTargetGHNID()).endTag(NS, "DeployedOn");
serializer.startTag(NS,"ErrorDescription").text("-").endTag(NS, "ErrorDescription");
}
serializer.startTag(NS,"DependenciesResolution");
//resolved dependencies
serializer.startTag(NS,"ResolvedDependencies");
for (Dependency dep : service.getResolvedDependencies(service.getTargetGHNID())) {
serializer.startTag(NS,"Dependency");
serializer.startTag(NS,"ServiceClass").text(dep.getService().getClazz()).endTag(NS, "ServiceClass");
serializer.startTag(NS,"ServiceName").text(dep.getService().getName()).endTag(NS, "ServiceName");
serializer.startTag(NS,"ServiceVersion").text(dep.getService().getVersion()).endTag(NS, "ServiceVersion");
serializer.startTag(NS,"PackageName").text(dep.getName()).endTag(NS, "PackageName");
serializer.startTag(NS,"PackageVersion").text(dep.getVersion()).endTag(NS, "PackageVersion");
serializer.endTag(NS,"Dependency");
}
serializer.endTag(NS,"ResolvedDependencies");
//missing dependencies
serializer.startTag(NS,"MissingDependencies");
for (Dependency dep : service.getMissingDependencies(service.getTargetGHNID())) {
serializer.startTag(NS,"Dependency");
serializer.startTag(NS,"ServiceClass").text(dep.getService().getClazz()).endTag(NS, "ServiceClass");
serializer.startTag(NS,"ServiceName").text(dep.getService().getName()).endTag(NS, "ServiceName");
serializer.startTag(NS,"ServiceVersion").text(dep.getService().getVersion()).endTag(NS, "ServiceVersion");
serializer.startTag(NS,"PackageName").text(dep.getName()).endTag(NS, "PackageName");
serializer.startTag(NS,"PackageVersion").text(dep.getVersion()).endTag(NS, "PackageVersion");
serializer.endTag(NS,"Dependency");
}
serializer.endTag(NS,"MissingDependencies");
serializer.endTag(NS,"DependenciesResolution");
}
//add the deployment report if it is available
String reportID = service.getTargetGHNID();
if (this.operation == OPERATION.AddResources)
serializer.startTag(NS,"DeploymentActivity");
else
serializer.startTag(NS,"UndeploymentActivity");
if (node2report.keySet().contains(reportID)) {
serializer.startTag(NS,"GHN");
serializer.startTag(NS,"ID").text(service.getTargetGHNID()).endTag(NS, "ID");
serializer.startTag(NS,"Host").text(node2report.get(reportID).getHost()).endTag(NS,"Host");
serializer.startTag(NS,"LastReportReceivedOn").text(ProfileDate.toXMLDateAndTime(node2report.get(reportID).getLastUpdate())).endTag(NS,"LastReportReceivedOn");
serializer.startTag(NS,"LastReportReceived");
serializer.startTag(NS,"Status").text(node2report.get(reportID).getStatus()).endTag(NS, "Status");
this.addGHNReport(serializer, node2report.get(reportID), service);
serializer.endTag(NS, "LastReportReceived");
serializer.endTag(NS,"GHN");
DeployedRunningInstance instance = this.getInstanceForService(service);
if ((this.operation == OPERATION.AddResources)
|| (this.operation == OPERATION.Create)){
if (instance != null) {
serializer.startTag(NS,"RelatedRunningInstance");
if (instance.isAlive())
serializer.startTag(NS, "ID").text(instance.getRIID()).endTag(NS, "ID");
serializer.startTag(NS,"Status").text(instance.isAlive()? "SUCCESS" : "FAILED").endTag(NS,"Status");
serializer.startTag(NS,"Message").text(instance.getMessage()).endTag(NS,"Message");
serializer.endTag(NS,"RelatedRunningInstance");
} else if (node2report.get(reportID).getStatus().compareToIgnoreCase("CLOSED") == 0 ) {
serializer.startTag(NS,"RelatedRunningInstance");
serializer.startTag(NS,"Status").text("FAILED").endTag(NS,"Status");
serializer.startTag(NS,"Message").text("The Deployer service did not detect any new instance of this service on the target gHN").endTag(NS,"Message");
serializer.endTag(NS,"RelatedRunningInstance");
}
}
} else {
if (service.isSuccess() && (this.brokerReportAvailable))
serializer.text("The report is still not available for this service");
else
serializer.text("No report");
}
if (this.operation == OPERATION.AddResources) {
serializer.endTag(NS,"DeploymentActivity");
}
else
serializer.endTag(NS,"UndeploymentActivity");
serializer.endTag(NS,"Service");
}
serializer.endTag(NS,"Services");
serializer.endTag(NS,"ResourceReport");
serializer.endDocument();
}
catch (Exception e) {
logger.error("The Resource Report does not have a valid serialisation", e);
throw new IOException("The Resource Report does not have a valid serialisation "+ e.getMessage());
}
finally {
report.close();
}
return report.toString();
}
/**
* Gets the deployed instance (if any) for the given service
* @param service the service
* @return the instance or null if no instances was found
*/
private DeployedRunningInstance getInstanceForService(ScopedDeployedService service) {
for (DeployedRunningInstance instance : this.instances) {
if ( (instance.getServiceClass().compareToIgnoreCase(service.getSourceService().getClazz()) == 0)
&& (instance.getServiceName().compareToIgnoreCase(service.getSourceService().getName()) == 0)) {
return instance;
}
}
return null;
}
/**
* @return the lastUpdate
*/
public Calendar getLastUpdate() {
return lastUpdate;
}
/**
* @return the resource report identifier
*/
public String getId() {
return id;
}
/**
* @return the scope this report belongs to
*/
public GCUBEScope getScope() {
return scope;
}
/**
* Saves the report on the local file system
*
* @throws IOException if the saving fails
*/
synchronized public void save() throws IOException {
FileWriter file = new FileWriter(getReportFile(this.id));
file.write(this.toXML());
file.close();
}
/**
* Loads the report from the file system
*
* @param id the report ID
* @return the report
* @throws IOException if the report does not have a valid serialization
*/
protected static Session load(String id) throws IOException {
Session report = new Session();
// load the report from its serialization
return report;
}
/**
* Loads the report from the file system
*
* @param id the report ID
* @return the string representation of the report
* @throws IOException if the report does not have a valid serialization
*/
protected static String loadAsString(String id) throws IOException {
// load the report serialization
File f = getReportFile(id);
if (! f.exists())
throw new IOException("Unable to find a serialized report with ID=" + id);
BufferedReader br = new BufferedReader(new FileReader(f));
StringBuilder report = new StringBuilder();
String s;
while((s = br.readLine()) != null) {
report.append(s);
}
br.close();
return report.toString();
}
private static File getReportFile(String id) throws IOException {
return new File(ServiceContext.getContext().getConfigurationFileAbsolutePath(reportDir) + File.separator + id + ".xml");
}
private void addGHNReport(KXmlSerializer serializer, DeployerReport report, ScopedDeployedService service) throws Exception {
serializer.startTag(NS, "Packages");
for (DeployedDependency dep: report.getDependencies()) {
if (this.isDepOfService(dep, service, report.getGHNID())) {
serializer.startTag(NS,"Package");
serializer.startTag(NS,"ServiceClass").text(dep.getService().getClazz()).endTag(NS, "ServiceClass");
serializer.startTag(NS,"ServiceName").text(dep.getService().getName()).endTag(NS, "ServiceName");
serializer.startTag(NS,"ServiceVersion").text(dep.getService().getVersion()).endTag(NS, "ServiceVersion");
serializer.startTag(NS,"PackageName").text(dep.getName()).endTag(NS, "PackageName");
serializer.startTag(NS,"PackageVersion").text(dep.getVersion()).endTag(NS, "PackageVersion");
serializer.startTag(NS,"Status").text(dep.getStatus()).endTag(NS, "Status");
serializer.startTag(NS,"Message").text(dep.getMessage()).endTag(NS, "Message");
serializer.endTag(NS,"Package");
}
}
serializer.endTag(NS, "Packages");
}
public synchronized void reportBrokerWork(boolean wasSuccessful, String brokerMessage) {
this.brokerReportAvailable = true;
this.brokerWasSuccessful = wasSuccessful;
this.brokerMessage = brokerMessage;
}
/**
* Adds newly deployed instances to the report. These instances are reported to be activated by the Deployer following a deployment
* request
*
* @param instances the new instances
*/
public void addDeployedInstances(Set<DeployedRunningInstance> instances) {
if ((instances == null) || (instances.size() == 0))
return;
this.instances.addAll(instances);
}
/**
* Checks if a dependency belongs to a specific service
* @param dep the dependency to check
* @param service the potential owner service
* @return true if the dependency belongs the service
*/
private boolean isDepOfService(DeployedDependency dep, ScopedDeployedService service,String targetGHNID) {
for (Dependency resolvedDependency : service.getResolvedDependencies(targetGHNID)) {
if (dep.equals((Dependency)resolvedDependency)) return true;
}
return false;
}
/**
* Checks whether the report is closed or no
* @return true if the report is closed, false otherwise
*/
public boolean isReportClosed() {
for ( ScopedResource resource : this.resources) {
if ((resource.getStatus() == STATUS.ADDREQUESTED) || (resource.getStatus() == STATUS.REMOVEREQUESTED))
return false;//the resource still need to be managed
}
for (ScopedDeployedService service : this.services) {
String reportID = service.getTargetGHNID();
if (service.isSuccess() && (this.brokerWasSuccessful)) {
//check the availability of the report and its status
if (! node2report.keySet().contains(reportID)) {
return false;
} else if (node2report.get(reportID).getStatus().compareToIgnoreCase("CLOSED") != 0){
return false;
}
}
}
return true;
}
public Set<ScopedDeployedService> getServices() {
return this.services;
}
/**
* Gets all the GHN reports received
* @return a map where the key is the GHN ID and the value is the related report
*/
public Map<String, DeployerReport> getAllGHNReports() {
return node2report;
}
/**
* @return the {@link OPERATION} related to this report
*/
public OPERATION getOperation() {
return operation;
}
public void setDeploymentPlan(String plan) {
this.deploymentPlan = plan;
}
public String getDeploymentPlan() throws IOException {
if (this.deploymentPlan == null)
throw new IOException("No Deployment Plan is available");
return this.deploymentPlan;
}
}

View File

@ -0,0 +1,154 @@
package org.gcube.vremanagement.resourcemanager.impl.state.observers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNodeManager;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode.NoGHNFoundException;
import org.gcube.vremanagement.resourcemanager.impl.operators.Operator.ACTION;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedRunningInstance;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.ResourceNotFound;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource.STATUS;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory.ServiceNotFoundException;
import org.gcube.vremanagement.resourcemanager.impl.state.ScopeState;
import org.gcube.vremanagement.resourcemanager.impl.state.ScopeState.OPERATION;
/**
*
* Performs management operations on {@link ScopedResource}s depending on their {@link STATUS}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class Executor extends ScopeObserver {
@Override
protected void scopeChanged(ScopeState scopeState) {
if (scopeState.getLastOperationPerformed() == OPERATION.EXECUTED)
return; //nothing to manage
boolean managed = false;
//RIs have to be managed first
//if a gHN is removed from a scope, the hosted RI are automatically removed too by gCore and
//this has to be avoided, otherwise the removeFromScope will not find them at removing time
Map<String, List<ScopedDeployedService>> toRemoveFromNode = new HashMap<String,List<ScopedDeployedService>>();
Set<ScopedResource> toRemoveFromScope = new HashSet<ScopedResource>();
Set<ScopedResource> toRemoveFromState = new HashSet<ScopedResource>();
for (ScopedResource resource : scopeState.getResourcesByType(ScopedRunningInstance.TYPE)){
switch (resource.getStatus()) {
case ADDREQUESTED: this.addResourceToScope(resource); managed = true; break;
case REMOVEREQUESTED:
try {
if (((ScopedRunningInstance)resource).isUndeployNeeded()) {
String hostedOnID = ((ScopedRunningInstance)resource).getHostedOnID();
try {
if (! toRemoveFromNode.containsKey(hostedOnID))
toRemoveFromNode.put(hostedOnID, new ArrayList<ScopedDeployedService>());
ScopedDeployedService service = ScopedResourceFactory.getRelatedService((ScopedRunningInstance)resource);
if (service.getNodes().size() > 1) {
logger.debug("Removing " + service + " from node " + resource.getHostedOn());
//there exist other instances of the service in the scope, we are going to remove only this one
service.scheduleUndeploy(VirtualNodeManager.getNode(hostedOnID, resource.getScope()));
service.setCallbackID(scopeState.getLastReport().getId());
scopeState.getLastReport().addResource(service);
scopeState.getLastReport().addService(service);
toRemoveFromNode.get(hostedOnID).add(service);
} else if (service.getNodes().size() == 1) {
//remove the service from the whole scope, since the instance to remove is deployed only once
logger.debug("Removing " + service + " from the scope");
scopeState.getLastReport().addResource(service);
scopeState.getLastReport().addService(service);
toRemoveFromScope.add(service);
} if (service.getNodes().size() < 0) {
//what's that??
((ScopedRunningInstance)resource).reportFailureOnSourceService("Can't find any node where the instance is deployed",new Exception("Can't find any node where the instance is deployed"));
resource.setStatus(STATUS.LOST);
toRemoveFromState.add(resource);
}
((ScopedRunningInstance)resource).wasSuccessful();
resource.setStatus(STATUS.REMOVED);
} catch (ServiceNotFoundException e) {
((ScopedRunningInstance)resource).reportFailureOnSourceService("Unable to find the source service. It might not be deployed by this Resource Manager instance",e);
resource.setStatus(STATUS.LOST);
toRemoveFromState.add(resource);
} catch (NoGHNFoundException e) {
((ScopedRunningInstance)resource).reportFailureOnSourceService("Unable to find the hosting gHN, ID=" + hostedOnID,e);
resource.setStatus(STATUS.LOST);
toRemoveFromState.add(resource);
}
} else {
this.removeResourceFromScope(resource);
toRemoveFromState.add(resource);
}
} catch (ResourceNotFound e) {
resource.setStatus(STATUS.LOST);
}
managed = true;break;
}
}
//now we can manage all the rest of the resources
for (ScopedResource resource : scopeState.getAllResources()) {
switch (resource.getStatus()) {
case ADDREQUESTED: this.addResourceToScope(resource); managed = true; break;
case REMOVEREQUESTED: this.removeResourceFromScope(resource); toRemoveFromState.add(resource); managed = true;break;
}
}
//notify the others for serialization and publication duties
if (managed) {
scopeState.setLastOperationPerformed(OPERATION.EXECUTED);
scopeState.notifyObservers();
}
//if there are services to undeploy, redo the procedure for them
for (String ghnid : toRemoveFromNode.keySet()) {
for (ScopedDeployedService service : toRemoveFromNode.get(ghnid)) {
try {
service.removeFromScope(ghnid);
} catch (Exception e) {
logger.error("Unable to undeploy " + service + " from " + ghnid, e);
}
}
}
//remove the services from the state or trigger the notifier to manage the service removed from specific nodes
if (toRemoveFromScope.size() > 0 )
scopeState.removeResources(toRemoveFromScope);
else if (toRemoveFromNode.keySet().size() > 0)
scopeState.notifyObservers();
//...and finally, a physical cleanup of the state
scopeState.forceResourceRemoval(toRemoveFromState);
}
private void addResourceToScope(ScopedResource resource) {
try {
resource.doAction(ACTION.ADD);
resource.setStatus(STATUS.ADDED);
} catch (ResourceNotFound e) {
//the resource does not exist..it will be removed from the internal state
resource.setStatus(STATUS.REMOVED);
} catch (Exception e) {
resource.setStatus(STATUS.LOST);
}
}
private void removeResourceFromScope(ScopedResource resource) {
try {
resource.doAction(ACTION.REMOVE);
resource.setStatus(STATUS.REMOVED);
} catch (ResourceNotFound e) {
//tolerate this exception... anyway it will be removed from the internal state
resource.setStatus(STATUS.REMOVED);
} catch (Exception e) {
//can't cope with this exception and don't know what to do
resource.setStatus(STATUS.LOST);
}
}
}

View File

@ -0,0 +1,42 @@
package org.gcube.vremanagement.resourcemanager.impl.state.observers;
import org.gcube.vremanagement.resourcemanager.impl.state.ProfileDate;
import org.gcube.vremanagement.resourcemanager.impl.state.PublishedScopeResource;
import org.gcube.vremanagement.resourcemanager.impl.state.ScopeState;
import static org.gcube.vremanagement.resourcemanager.impl.state.ScopeState.OPERATION;
/**
*
* Synchronizes the resources' list with the IS
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class Publisher extends ScopeObserver {
@Override
protected void scopeChanged(ScopeState scopeState) {
if (scopeState.getLastOperationPerformed() == OPERATION.PUBLISHED)
return; //no need to republish and loop on this
try {
PublishedScopeResource resource = PublishedScopeResource.getResource(scopeState.getScope());
try {
logger.trace("PUBLISHER: Start time " + ProfileDate.toXMLDateAndTime(scopeState.getStartTime()));
resource.synchWithLocalState(scopeState);
resource.publish();
scopeState.setLastOperationPerformed(OPERATION.PUBLISHED);
scopeState.notifyObservers();//force to serialize after publishing (not nice, thought)
} catch (Exception e) {
logger.fatal("Can't publish the Scope Resource in the IS");
throw e;
}
} catch (Exception e) {
logger.fatal("An error occured in the resource's publishing", e);
}
}
}

View File

@ -0,0 +1,41 @@
package org.gcube.vremanagement.resourcemanager.impl.state.observers;
import java.util.Observable;
import java.util.Observer;
import org.gcube.common.core.utils.logging.GCUBELog;
import org.gcube.vremanagement.resourcemanager.impl.state.ScopeState;
/**
*
* Base observer for {@link ScopeState}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public abstract class ScopeObserver implements Observer {
protected GCUBELog logger = new GCUBELog(this.getClass());
public void update(Observable observed, Object arg) {
logger.trace(this.getClass().getSimpleName() + " Observer has been notified");
ScopeState resources;
if (ScopeState.class.isAssignableFrom(observed.getClass()))
resources = (ScopeState) observed;
else
throw new IllegalArgumentException("Can't manage the observed obj");
//notify subclasses
this.scopeChanged(resources);
}
/**
* Manages the modified scope
*
* @param scopeState the scope
*/
protected abstract void scopeChanged(ScopeState scopeState);
}

View File

@ -0,0 +1,121 @@
package org.gcube.vremanagement.resourcemanager.impl.state.observers;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
import org.gcube.vremanagement.resourcemanager.impl.deployment.VirtualNode;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedAnyResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedDeployedService;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedGHN;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedRunningInstance;
import org.gcube.vremanagement.resourcemanager.impl.resources.types.MultiKeysMap;
import org.gcube.vremanagement.resourcemanager.impl.state.RawScopeState;
import org.gcube.vremanagement.resourcemanager.impl.state.ScopeState;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.QNameMap;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import javax.xml.namespace.QName;
/**
*
* Serializer for {@link ScopeState}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class Serializer extends ScopeObserver {
public final static File persistentList = ServiceContext.getContext().getPersistentFile("ScopedResourceList.xml", true);
private final static String namespace = "http://gcube-system.org/namespaces/resourcemanager/manager/xsd/state";
/**
* Serializes the notified list on the file system
* @param scopeState the list to serialize
*/
@Override
protected synchronized void scopeChanged(final ScopeState scopeState) {
try {
store(scopeState);
//scopeState.setLastOperationPerformed(OPERATION.SERIALIZED); //if we record this, the others observer manage the list with no need
//we do not notify the others obs here, since the serialization does not imply any change in the list
} catch (IOException e) {
logger.fatal("Cannot serialize the resource's list", e);
}
}
public synchronized static void store(final ScopeState scopeState) throws IOException {
QNameMap qmap = new QNameMap();
qmap.registerMapping(new QName(namespace, ""), RawScopeState.class);
StaxDriver driver = new StaxDriver(qmap);
driver.setRepairingNamespace(false);
XStream stream = new XStream(driver);
prepareStream(stream);
FileOutputStream fs = new FileOutputStream(persistentList);
stream.toXML(scopeState.getRawScopeState(), fs);
fs.close();
}
/**
* Loads the list of {@link ScopedResource} from the local file system
* @param the actual scope
* @return the resource list, if any
* @throws IOException if the list was not found on the file system
*/
public synchronized static void load(ScopeState scopeState, GCUBEScope scope) throws IOException {
if (! persistentList.exists())
throw new IOException();
//try to load the local list of resources
QNameMap qmap = new QNameMap();
qmap.registerMapping(new QName(namespace, ""), RawScopeState.class);
StaxDriver driver = new StaxDriver(qmap);
driver.setRepairingNamespace(false);
XStream stream = new XStream(driver);
prepareStream(stream);
RawScopeState state = (RawScopeState) stream.fromXML(new FileInputStream((persistentList)));
//a bit of sanity checks....
if ((state == null) || (state.getScope() == null) || (state.getScope().getName().compareTo(scope.getName()) != 0))
throw new IOException();
//inject the state
scopeState.setRawScopeState(state);
}
private static void prepareStream(XStream stream) {
stream.processAnnotations(RawScopeState.class);
stream.alias(RawScopeState.class.getSimpleName(), RawScopeState.class);
stream.processAnnotations(ScopedResource.class);
stream.alias(ScopedResource.class.getSimpleName(), ScopedResource.class);
stream.alias(ScopedGHN.class.getSimpleName(), ScopedGHN.class);
stream.processAnnotations(ScopedGHN.class);
stream.alias(ScopedRunningInstance.class.getSimpleName(), ScopedRunningInstance.class);
stream.processAnnotations(ScopedRunningInstance.class);
stream.alias(ScopedDeployedService.class.getSimpleName(), ScopedDeployedService.class);
stream.processAnnotations(ScopedDeployedService.class);
stream.alias(ScopedAnyResource.class.getSimpleName(), ScopedAnyResource.class);
stream.processAnnotations(ScopedAnyResource.class);
stream.alias("ResourceList", MultiKeysMap.class);
stream.alias("ResourceData", Map.class);
stream.alias("Scope", GCUBEScope.class);
stream.alias("ScopeType", GCUBEScope.Type.class);
stream.alias("VirtualNode", VirtualNode.class);
}
}

View File

@ -0,0 +1,112 @@
package org.gcube.vremanagement.resourcemanager.impl.state;
import java.util.HashSet;
import java.util.Set;
import org.gcube.common.core.resources.GCUBEHostingNode;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory;
import com.thoughtworks.xstream.XStream;
import static org.junit.Assert.*;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
/**
*
* JUnit test class for {@link ScopeState}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class ResourceListTest {
private static final String SCOPE = "/gcube/devsec";
private static final String NAME = "test-list";
private static final String DESCRIPTION = "This is a test for scoped resources";
private ScopeState list;
@Test
public void initializeList(String name) {
list = new ScopeState();
list.initialize(GCUBEScope.getScope(SCOPE), NAME, false, DESCRIPTION);
}
protected void setUp() throws Exception {
}
@Test
public void testAddResource()throws Exception {
Set<ScopedResource> resourceToAdd = new HashSet<ScopedResource>();
ScopedResource ghn = ScopedResourceFactory.newResource("ID1", GCUBEHostingNode.TYPE, GCUBEScope.getScope(SCOPE));
resourceToAdd.add(ghn);
list.addResources(resourceToAdd);
Assert.assertEquals(1, list.getResourcesByType(ghn.getType()).size());
ScopedResource ghn2 = ScopedResourceFactory.newResource("ID2", GCUBEHostingNode.TYPE, GCUBEScope.getScope(SCOPE));
resourceToAdd.add(ghn2);
list.addResources(resourceToAdd);
Assert.assertEquals(2, list.getResourcesByType(ghn2.getType()).size());
ScopedResource ri = ScopedResourceFactory.newResource("RI1", GCUBERunningInstance.TYPE, GCUBEScope.getScope(SCOPE));
ri.setHostedON("node1.p:8080");
resourceToAdd.add(ri);
list.addResources(resourceToAdd);
Assert.assertEquals(3, list.getResourcesByType(ri.getType()).size());
}
public void testGetResourcesByType() {
fail("Not yet implemented");
}
@Test
public void testChangeDescription() {
list.changeDescription("This is a new description");
}
public void testRemoveAllResourcesByType() {
fail("Not yet implemented");
}
@Test
public void testRemoveResource() throws Exception {
Set<ScopedResource> resourceToRemove = new HashSet<ScopedResource>();
ScopedResource ghn = ScopedResourceFactory.newResource("ID1", GCUBEHostingNode.TYPE, GCUBEScope.getScope(SCOPE));
resourceToRemove.add(ghn);
list.removeResources(resourceToRemove);
}
@Test
public void testCleanList() {
}
public void testAddObserver() {
fail("Not yet implemented");
}
public void testDeleteObserver() {
fail("Not yet implemented");
}
@Test
protected void tearDown() throws Exception {
XStream stream = new XStream();
stream.processAnnotations(ScopeState.class);
System.out.println(stream.toXML(list));
}
}

View File

@ -0,0 +1,128 @@
package org.gcube.vremanagement.resourcemanager.impl.resources.types;
import org.gcube.common.core.resources.GCUBEHostingNode;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
/**
*
* JUnit test for {@link MultiKeysMap}
*
* @author Manuele Simi (ISTI-CNR)
*
*/
public class MultiKeysMapTest {
private MultiKeysMap<String, String, ScopedResource> map;
public MultiKeysMapTest(String name) {
super(name);
this.map = new MultiKeysMap<String, String, ScopedResource>();
}
@Test
public void testPut() throws Exception {
System.out.println("Adding resources test");
System.out.println("Map before the method");
printMap();
ScopedResource ghn = ScopedResourceFactory.newResource("ID1", GCUBEHostingNode.TYPE, GCUBEScope.getScope("/gcube"));
map.put(ghn.getId(), ghn.getType(), ghn);
Assert.assertEquals(1, map.values().size());
ScopedResource ghn2 = ScopedResourceFactory.newResource("ID2", GCUBEHostingNode.TYPE, GCUBEScope.getScope("/gcube"));
map.put(ghn2.getId(), ghn2.getType(), ghn2);
Assert.assertEquals(2, map.values().size());
ScopedResource ri = ScopedResourceFactory.newResource("RI1", GCUBERunningInstance.TYPE, GCUBEScope.getScope("/gcube"));
map.put(ri.getId(), ri.getType(), ri);
Assert.assertEquals(3, map.values().size());
System.out.println("Map after the method");
printMap();
}
@Test
public void testRemoveValuesByPrimaryKey() throws Exception {
testPut();
System.out.println("testRemoveValuesByPrimaryKey");
map.removeValuesByPrimaryKey("ID2");
System.out.println("Map after testRemoveValuesByPrimaryKey method");
printMap();
}
@Test
public void testRemoveValue() throws Exception {
ScopedResource ghn = ScopedResourceFactory.newResource("ID1", GCUBEHostingNode.TYPE, GCUBEScope.getScope("/gcube"));
map.removeValue(ghn);
}
@Test
public void testRemoveValuesBySecondaryKey() throws Exception {
ScopedResource ri = ScopedResourceFactory.newResource("RI1", GCUBERunningInstance.TYPE, GCUBEScope.getScope("/gcube"));
map.removeValuesBySecondaryKey(ri.getType());
}
@Test
public void testGetValuesByPrimaryKey() {
fail("Not yet implemented");
}
@Test
public void testGetValuesBySecondaryKey() {
fail("Not yet implemented");
}
@Test
public void testPrimaryKeySet() {
fail("Not yet implemented");
}
@Test
public void testSecondaryKeySet() {
fail("Not yet implemented");
}
@Test
public void testValues() {
for (ScopedResource resource : map.values()) {
System.out.println("Resource Value ID = " + resource.getId());
}
}
@Test
public void testClean() {
map.clean();
}
@Test
public void printMap() {
System.out.println("Values by KEY1:");
for (String key1 : map.primaryKeySet()) {
for (ScopedResource resource : map.getValuesByPrimaryKey(key1))
System.out.println( key1 + " ->" +resource.getId());
}
System.out.println("Values by KEY2:");
for (String key2 : map.secondaryKeySet()) {
for (ScopedResource resource : map.getValuesBySecondaryKey(key2))
System.out.println( key2 + " ->" +resource.getId());
}
System.out.println("Values:");
for (ScopedResource resource : map.values()) {
System.out.println(resource.getId());
}
}
}

View File

@ -0,0 +1,75 @@
package org.gcube.vremanagement.resourcemanager.impl.resources.types;
import java.util.Observable;
import java.util.Observer;
import org.gcube.common.core.resources.GCUBEHostingNode;
import org.gcube.common.core.resources.GCUBERunningInstance;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResource;
import org.gcube.vremanagement.resourcemanager.impl.resources.ScopedResourceFactory;
import org.gcube.vremanagement.resourcemanager.impl.resources.types.MultiKeysMap;
import static org.junit.Assert.*;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class MultiKeysTester {
MultiKeysMap<String, String, ScopedResource> map;
@Test
public void createMap() {
this.map = new MultiKeysMap<String, String, ScopedResource>();
}
@Test
public void addObserver() {
this.createMap();
//map.addObserver(new CollectionWatcher());
}
@Test
public void populateMap() throws Exception {
ScopedResource ghn = ScopedResourceFactory.newResource("ID1", GCUBEHostingNode.TYPE,GCUBEScope.getScope("/gcube"));
map.put(ghn.getId(), ghn.getType(), ghn);
ScopedResource ghn2 = ScopedResourceFactory.newResource("ID2", GCUBEHostingNode.TYPE, GCUBEScope.getScope("/gcube"));
map.put(ghn2.getId(), ghn2.getType(), ghn2);
ScopedResource ri = ScopedResourceFactory.newResource("RI1", GCUBERunningInstance.TYPE, GCUBEScope.getScope("/gcube"));
map.put(ri.getId(), ri.getType(), ri);
printMap(map);
map.removeValuesBySecondaryKey(ri.getType());
printMap(map);
map.removeValue(ghn);
printMap(map);
}
@Test
public void printMap(MultiKeysMap<String, String, ScopedResource> map) {
System.out.println("Values by KEY1:");
for (String key1 : map.primaryKeySet()) {
for (ScopedResource resource : map.getValuesByPrimaryKey(key1))
System.out.println( key1 + " ->" +resource.getId());
}
System.out.println("Values by KEY2:");
for (String key2 : map.secondaryKeySet()) {
for (ScopedResource resource : map.getValuesBySecondaryKey(key2))
System.out.println( key2 + " ->" +resource.getId());
}
System.out.println("Values:");
for (ScopedResource resource : map.values()) {
System.out.println(resource.getId());
}
}
public class CollectionWatcher implements Observer {
public void update(Observable o, Object arg) {
System.out.println("Notified");
}
}
}

View File

@ -0,0 +1,108 @@
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.gcube.resourcemanagement</groupId>
<artifactId>resource-manager</artifactId>
<version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>resource-manager-stubs</artifactId>
<name>Resource Manager Stubs</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>gcf</artifactId>
<version>[1.4.0-SNAPSHOT,1.5.0)</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-config</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<outputDirectory>${project.build.outputDirectory}/META-INF</outputDirectory>
<resources>
<resource>
<directory>${configDirectory}</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.gcube.tools</groupId>
<artifactId>maven-service-plugin</artifactId>
<configuration>
<wsdls>
<wsdl>
<name>ResourceManager</name>
<relativePackage>stubs.resourcemanager</relativePackage>
<namespace>${namespace}</namespace>
<additionalMappings>-Nhttp://gcube-system.org/common/vremanagement/types=${basepackage}.stubs.common</additionalMappings>
</wsdl>
</wsdls>
</configuration>
<executions>
<execution>
<id>generate-stubs</id>
<goals>
<goal>stub-gen</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>process-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/target/generated-sources/stubs</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,85 @@
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.gcube.resourcemanagement</groupId>
<artifactId>resource-manager</artifactId>
<version>1.2.0-SNAPSHOT</version>
</parent>
<artifactId>resource-manager-test-suite</artifactId>
<name>Resource Manager test suite</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- reactor dependencies -->
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>gcf</artifactId>
<version>[1.4.0-SNAPSHOT,1.5.0)</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.resourcemanagement</groupId>
<artifactId>resource-manager-stubs</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.gcube.resourcemanagement</groupId>
<artifactId>resource-manager-service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-config</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<outputDirectory>${project.build.outputDirectory}/META-INF</outputDirectory>
<resources>
<resource>
<directory>${configDirectory}</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

302
wsdl/ResourceManager.wsdl Normal file
View File

@ -0,0 +1,302 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="ResourceManager"
targetNamespace="http://gcube-system.org/namespaces/vremanagement/resourcemanager"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://gcube-system.org/namespaces/vremanagement/resourcemanager"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:provider="http://gcube-system.org/namespaces/common/core/porttypes/GCUBEProvider"
xmlns:coretypes="http://gcube-system.org/namespaces/common/core/types"
xmlns:corefaults="http://gcube-system.org/namespaces/common/core/faults"
xmlns:vretypes="http://gcube-system.org/common/vremanagement/types"
xmlns:wsrlw="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl"
xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd"
xmlns:wsntw="http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.wsdl"
xmlns:wsdlpp="http://www.globus.org/namespaces/2004/10/WSDLPreprocessor"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<import namespace="http://gcube-system.org/namespaces/common/core/porttypes/GCUBEProvider" location="../gcube/common/core/providers/GCUBEProvider.wsdl"/>
<import namespace="http://gcube-system.org/namespaces/common/core/faults" location="../gcube/common/core/faults/GCUBEFaults.wsdl"/>
<import namespace="http://gcube-system.org/common/vremanagement/types" location="VREManagementTypes.wsdl"/>
<!--============================================================
T Y P E S
============================================================-->
<types>
<xsd:schema targetNamespace="http://gcube-system.org/namespaces/vremanagement/resourcemanager"
xmlns:tns="http://gcube-system.org/namespaces/vremanagement/resourcemanager"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://gcube-system.org/namespaces/common/core/types" schemaLocation="../gcube/common/core/types/GCUBETypes.xsd"/>
<xsd:import namespace="http://gcube-system.org/common/vremanagement/types" schemaLocation="VREManagementTypes.xsd"/>
<xsd:simpleType name="resourceID">
<xsd:restriction base="xsd:string" />
</xsd:simpleType>
<xsd:element name="VOID">
<xsd:complexType/>
</xsd:element>
<xsd:complexType name="ServiceItem">
<xsd:sequence>
<xsd:element name="ServiceClass" type="xsd:string"/>
<xsd:element name="ServiceName" type="xsd:string"/>
<xsd:element name="ServiceVersion" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element name="GHN" type="tns:resourceID" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ServiceList">
<xsd:sequence>
<xsd:element name="service" type="tns:ServiceItem" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element name="GHN" type="tns:resourceID" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ResourceItem">
<xsd:sequence>
<xsd:element name="ID" type="tns:resourceID"/>
<xsd:element name="Type" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ResourceList">
<xsd:sequence>
<xsd:element name="resource" type="tns:ResourceItem" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="addResourcesParameters">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="services" type="tns:ServiceList" minOccurs="0" maxOccurs="1"/>
<xsd:element name="resources" type="tns:ResourceList" minOccurs="0" maxOccurs="1"/>
<xsd:element name="targetScope" type="coretypes:scope" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="removeResourcesParameters">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="services" type="tns:ServiceList" minOccurs="0" maxOccurs="1"/>
<xsd:element name="resources" type="tns:ResourceList" minOccurs="0" maxOccurs="1"/>
<xsd:element name="targetScope" type="coretypes:scope" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="sendReportParameters">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="callbackID" type="xsd:string"/>
<xsd:element name="report" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="ScopeOption">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="value" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="optionsParameters">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ScopeOptionList" type="tns:ScopeOption" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="disposeScopeParameters">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Name" type="coretypes:scope"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="createScopeParameters">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Name" type="coretypes:scope"/>
<xsd:element name="ServiceMap" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="tns:optionsParameters"/>
<xsd:element ref="tns:addResourcesParameters"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="GHN" type="tns:resourceID"/>
<xsd:element name="reportID" type="xsd:string"/>
<xsd:element name="report" type="xsd:string"/>
<xsd:element name="InvalidScopeFaultType">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="corefaults:GCUBEUnrecoverableFault">
<xsd:sequence/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="InvalidOptionsFaultType">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="corefaults:GCUBEUnrecoverableFault">
<xsd:sequence/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="ResourcesCreationFaultType">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="corefaults:GCUBEUnrecoverableFault">
<xsd:sequence/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="ResourcesRemovalFaultType">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="corefaults:GCUBEUnrecoverableFault">
<xsd:sequence/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="NoSuchReportFaultType">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="corefaults:GCUBEUnrecoverableFault">
<xsd:sequence/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<!--============================================================
M E S S A G E S
============================================================-->
<message name="AddResourcesInputMessage">
<part name="request" element="tns:addResourcesParameters"/>
</message>
<message name="ReportID">
<part name="request" element="tns:reportID"/>
</message>
<message name="RemoveResourcesInputMessage">
<part name="request" element="tns:removeResourcesParameters"/>
</message>
<message name="SendReportInputMessage">
<part name="request" element="tns:sendReportParameters"/>
</message>
<message name="ChangeScopeOptionsInputMessage">
<part name="request" element="tns:optionsParameters"/>
</message>
<message name="DisposeScopeInputMessage">
<part name="request" element="tns:disposeScopeParameters"/>
</message>
<message name="CreateScopeInputMessage">
<part name="request" element="tns:createScopeParameters"/>
</message>
<message name="GetReportInputMessage">
<part name="request" element="tns:reportID"/>
</message>
<message name="GetReportResponseMessage">
<part name="request" element="tns:report"/>
</message>
<message name="VoidMessage">
<part name="response" element="tns:VOID"/>
</message>
<wsdl:message name="InvalidScopeFaultMessage">
<part name="fault" element="tns:InvalidScopeFaultType"/>
</wsdl:message>
<wsdl:message name="InvalidOptionsFaultMessage">
<part name="fault" element="tns:InvalidOptionsFaultType"/>
</wsdl:message>
<wsdl:message name="ResourcesCreationFaultMessage">
<part name="fault" element="tns:ResourcesCreationFaultType"/>
</wsdl:message>
<wsdl:message name="ResourcesRemovalFaultMessage">
<part name="fault" element="tns:ResourcesRemovalFaultType"/>
</wsdl:message>
<wsdl:message name="NoSuchReportFaultMessage">
<part name="fault" element="tns:NoSuchReportFaultType"/>
</wsdl:message>
<!--============================================================
P O R T T Y P E
============================================================-->
<portType name="ResourceManagerPortType"
wsdlpp:extends="provider:GCUBEProvider">
<operation name="AddResources">
<input message="tns:AddResourcesInputMessage"/>
<output message="tns:ReportID"/>
<fault name="fault" message="tns:ResourcesCreationFaultMessage"/>
<fault name="fault1" message="tns:InvalidScopeFaultMessage"/>
</operation>
<operation name="RemoveResources">
<input message="tns:RemoveResourcesInputMessage"/>
<output message="tns:ReportID"/>
<fault name="fault" message="tns:ResourcesRemovalFaultMessage"/>
<fault name="fault1" message="tns:InvalidScopeFaultMessage"/>
</operation>
<operation name="ChangeScopeOptions">
<input message="tns:ChangeScopeOptionsInputMessage"/>
<output message="tns:VoidMessage"/>
<fault name="fault" message="tns:InvalidOptionsFaultMessage"/>
<fault name="fault1" message="tns:InvalidScopeFaultMessage"/>
</operation>
<operation name="DisposeScope">
<input message="tns:DisposeScopeInputMessage"/>
<output message="tns:ReportID"/>
<fault name="fault" message="tns:InvalidScopeFaultMessage"/>
</operation>
<operation name="CreateScope">
<input message="tns:CreateScopeInputMessage"/>
<output message="tns:ReportID"/>
<fault name="fault1" message="tns:InvalidScopeFaultMessage"/>
<fault name="fault2" message="tns:InvalidOptionsFaultMessage"/>
<fault name="fault3" message="tns:ResourcesCreationFaultMessage"/>
</operation>
<operation name="SendReport">
<input message="tns:SendReportInputMessage"/>
<output message="tns:VoidMessage"/>
<fault name="fault" message="corefaults:GCUBEFaultMessage"/>
</operation>
<operation name="GetReport">
<input message="tns:GetReportInputMessage"/>
<output message="tns:GetReportResponseMessage"/>
<fault name="fault1" message="tns:InvalidScopeFaultMessage"/>
<fault name="fault2" message="tns:NoSuchReportFaultMessage"/>
</operation>
</portType>
</definitions>

27
wsdl/VREManagementTypes.wsdl Executable file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="VREManagementTypes"
targetNamespace="http://gcube-system.org/common/vremanagement/types"
xmlns:tns="http://gcube-system.org/common/vremanagement/types"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<!--============================================================
T Y P E S
============================================================-->
<types>
<xs:schema
targetNamespace="http://gcube-system.org/common/vremanagement/types"
xmlns:tns="http://gcube-system.org/common/vremanagement/types">
<!-- <xs:import namespace="http://schemas.xmlsoap.org/ws/2004/03/addressing" schemaLocation="../../../../ws/addressing/WS-Addressing.xsd" /> -->
<xs:import namespace="http://schemas.xmlsoap.org/ws/2004/03/addressing" schemaLocation="../ws/addressing/WS-Addressing.xsd" />
<xs:include schemaLocation="VREManagementTypes.xsd" />
</xs:schema>
</types>
</definitions>

80
wsdl/VREManagementTypes.xsd Executable file
View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://gcube-system.org/common/vremanagement/types"
xmlns:tns="http://gcube-system.org/common/vremanagement/types"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="DeployInfoStatus">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="ghnID" type="xs:string"/>
<xs:element name="packageInfo" type="tns:PackageInfoStatus"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="DeployInfo">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="ghnID" type="xs:string"/>
<xs:element name="packageInfo" type="tns:PackageInfo"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Pair">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="name" type="xs:string"/>
<xs:element name="value" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PackageInfo">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="serviceName" type="xs:string"/>
<xs:element name="serviceClass" type="xs:string"/>
<xs:element name="serviceVersion" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="version" type="xs:string"/>
<xs:element name="Options" type="tns:Pair" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PackageInfoStatus">
<xs:sequence>
<xs:element name="package" type="tns:PackageInfo" />
<xs:element name="status" type="xs:string"/>
<xs:element name="message" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ServiceInfoStatus">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="serviceName" type="xs:string"/>
<xs:element name="serviceClass" type="xs:string"/>
<xs:element name="ghnName" type="xs:string"/>
<xs:element name="status" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="deployMessage">
<xs:sequence>
<xs:element name="serviceName" type="xs:string"/>
<xs:element name="serviceClass" type="xs:string"/>
<xs:element name="ghnID" type="xs:string" />
<xs:element name="Scope" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="feedbackMessage">
<xs:sequence>
<xs:element name="callbackID" type="xs:string" />
<xs:element name="log" type="xs:string" />
<xs:element name="type" type="xs:string" />
<xs:element name="runningInstanceIDsList" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="packageInfoStatus" type="tns:PackageInfoStatus" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>