My-container testing, new portTypes implementation, multi-scope starting accepted
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/vre-management/ResourceManager@55833 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
f2293120e5
commit
ae29c765cb
|
@ -4,8 +4,8 @@
|
|||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<service name="gcube/vremanagement/resourcemanager/binder" provider="Handler" use="literal" style="document">
|
||||
<parameter name="className" value="org.gcube.vremanagement.resourcemanager.portTypes.ResourceManager"/>
|
||||
<wsdlFile>share/schema/org.gcube.vremanagement.resourcemanager/ResourceBinder_service.wsdl</wsdlFile>
|
||||
<parameter name="className" value="org.gcube.vremanagement.resourcemanager.porttypes.ResourceBinder"/>
|
||||
<wsdlFile>share/schema/resourcemanager/ResourceBinder_service.wsdl</wsdlFile>
|
||||
<parameter name="allowedMethods" value="*"/>
|
||||
<parameter name="handlerClass" value="org.globus.axis.providers.RPCProvider"/>
|
||||
<parameter name="scope" value="Application"/>
|
||||
|
@ -15,8 +15,8 @@
|
|||
</service>
|
||||
|
||||
<service name="gcube/vremanagement/resourcemanager/reporting" provider="Handler" use="literal" style="document">
|
||||
<parameter name="className" value="org.gcube.vremanagement.resourcemanager.portTypes.ResourceManager"/>
|
||||
<wsdlFile>share/schema/org.gcube.vremanagement.resourcemanager/Reporting_service.wsdl</wsdlFile>
|
||||
<parameter name="className" value="org.gcube.vremanagement.resourcemanager.porttypes.Reporting"/>
|
||||
<wsdlFile>share/schema/resourcemanager/Reporting_service.wsdl</wsdlFile>
|
||||
<parameter name="allowedMethods" value="*"/>
|
||||
<parameter name="handlerClass" value="org.globus.axis.providers.RPCProvider"/>
|
||||
<parameter name="scope" value="Application"/>
|
||||
|
@ -26,8 +26,8 @@
|
|||
</service>
|
||||
|
||||
<service name="gcube/vremanagement/resourcemanager/scopecontroller" provider="Handler" use="literal" style="document">
|
||||
<parameter name="className" value="org.gcube.vremanagement.resourcemanager.portTypes.ResourceManager"/>
|
||||
<wsdlFile>share/schema/org.gcube.vremanagement.resourcemanager/ScopeController_service.wsdl</wsdlFile>
|
||||
<parameter name="className" value="org.gcube.vremanagement.resourcemanager.porttypes.ScopeController"/>
|
||||
<wsdlFile>share/schema/resourcemanager/ScopeController_service.wsdl</wsdlFile>
|
||||
<parameter name="allowedMethods" value="*"/>
|
||||
<parameter name="handlerClass" value="org.globus.axis.providers.RPCProvider"/>
|
||||
<parameter name="scope" value="Application"/>
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
<dependency>
|
||||
<groupId>org.gcube.tools</groupId>
|
||||
<artifactId>my-container</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>1.1.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -6,7 +6,10 @@ 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.porttypes.ResourceManager;
|
||||
import org.gcube.vremanagement.resourcemanager.impl.state.InstanceState;
|
||||
import org.gcube.vremanagement.resourcemanager.porttypes.ResourceBinder;
|
||||
import org.globus.wsrf.NoSuchResourceException;
|
||||
import org.globus.wsrf.ResourceException;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -19,6 +22,9 @@ public class ServiceContext extends GCUBEServiceContext {
|
|||
|
||||
static ServiceContext cache = new ServiceContext();
|
||||
|
||||
/** Singleton resource name*/
|
||||
public static final String SINGLETON_RESOURCE_KEY = "VREManagerState";
|
||||
|
||||
|
||||
/**
|
||||
* Gets the current service context
|
||||
|
@ -40,11 +46,6 @@ public class ServiceContext extends GCUBEServiceContext {
|
|||
@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());
|
||||
|
@ -52,13 +53,24 @@ public class ServiceContext extends GCUBEServiceContext {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the singleton resource
|
||||
*
|
||||
* @return the {@link InstanceState}
|
||||
* @throws NoSuchResourceException
|
||||
* @throws ResourceException
|
||||
*/
|
||||
public InstanceState getResource() throws NoSuchResourceException, ResourceException{
|
||||
return (InstanceState) StatefulPortTypeContext.getContext().getWSHome().find(StatefulPortTypeContext.getContext().makeKey(SINGLETON_RESOURCE_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates/updates the Deployer stateful resource
|
||||
*
|
||||
* @author Manuele Simi (ISTI-CNR)
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
protected class HStateScheduler extends GCUBEScheduledHandler {
|
||||
|
||||
public HStateScheduler(long interval, Mode mode) {
|
||||
|
@ -91,7 +103,7 @@ public class ServiceContext extends GCUBEServiceContext {
|
|||
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));
|
||||
StatefulPortTypeContext.getContext().getWSHome().create(StatefulPortTypeContext.getContext().makeKey(ResourceBinder.SINGLETON_RESOURCE_KEY));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ public class StatefulPortTypeContext extends GCUBEStatefulPortTypeContext {
|
|||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return "http://gcube-system.org/namespaces/vremanagement/vremanager";
|
||||
return "http://gcube-system.org/namespaces/vremanagement/resourcemanager";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
package org.gcube.vremanagement.resourcemanager.porttypes;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
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.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.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.globus.wsrf.NoSuchResourceException;
|
||||
import org.globus.wsrf.ResourceException;
|
||||
|
||||
import org.gcube.vremanagement.resourcemanager.stubs.reporting.*;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <em>Reporting</em> portType implementation
|
||||
*
|
||||
* @author Manuele Simi (CNR)
|
||||
*
|
||||
*/
|
||||
public class Reporting 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();
|
||||
}
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
package org.gcube.vremanagement.resourcemanager.porttypes;
|
||||
|
||||
|
||||
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.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.operators.AddResourcesOperator;
|
||||
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.InstanceState;
|
||||
import org.gcube.vremanagement.resourcemanager.impl.state.Session.OPERATION;
|
||||
import org.globus.wsrf.NoSuchResourceException;
|
||||
import org.globus.wsrf.ResourceException;
|
||||
|
||||
import org.gcube.vremanagement.resourcemanager.stubs.binder.*;
|
||||
import org.gcube.vremanagement.resourcemanager.stubs.common.InvalidScopeFaultType;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <em>ResourceBinder</em> portType implementation
|
||||
*
|
||||
* @author Manuele Simi (CNR)
|
||||
*
|
||||
*/
|
||||
public class ResourceBinder 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 ResourceBinder#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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,319 +0,0 @@
|
|||
package org.gcube.vremanagement.resourcemanager.porttypes;
|
||||
|
||||
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.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;
|
||||
|
||||
import org.gcube.vremanagement.resourcemanager.stubs.binder.*;
|
||||
import org.gcube.vremanagement.resourcemanager.stubs.common.InvalidScopeFaultType;
|
||||
import org.gcube.vremanagement.resourcemanager.stubs.scontroller.*;
|
||||
import org.gcube.vremanagement.resourcemanager.stubs.reporting.*;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <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 void 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package org.gcube.vremanagement.resourcemanager.porttypes;
|
||||
|
||||
|
||||
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.operators.DisposeScopeOperator;
|
||||
import org.gcube.vremanagement.resourcemanager.impl.operators.OperatorConfig;
|
||||
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;
|
||||
|
||||
import org.gcube.vremanagement.resourcemanager.stubs.common.InvalidScopeFaultType;
|
||||
import org.gcube.vremanagement.resourcemanager.stubs.scontroller.*;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <em>ScopeController</em> portType implementation
|
||||
*
|
||||
* @author Manuele Simi (CNR)
|
||||
*
|
||||
*/
|
||||
public class ScopeController extends GCUBEPortType {
|
||||
|
||||
/**
|
||||
* Object logger.
|
||||
*/
|
||||
protected final GCUBELog logger = new GCUBELog(this, ServiceContext.getContext());
|
||||
|
||||
@Override
|
||||
protected GCUBEServiceContext getServiceContext() {
|
||||
return ServiceContext.getContext();
|
||||
}
|
||||
/**
|
||||
* 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 void createScope(CreateScopeParameters params)
|
||||
throws InvalidScopeFaultType, InvalidOptionsFaultType, 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package org.gcube.vremanagement.resourcemanager.impl;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
|
||||
import javax.inject.Inject;
|
||||
import org.gcube.common.core.contexts.GCUBEServiceContext.Status;
|
||||
import org.gcube.common.mycontainer.Deployment;
|
||||
import org.gcube.common.mycontainer.Gar;
|
||||
import org.gcube.common.mycontainer.MyContainer;
|
||||
import org.gcube.common.mycontainer.MyContainerTestRunner;
|
||||
import org.gcube.vremanagement.resourcemanager.impl.contexts.ServiceContext;
|
||||
import org.gcube.vremanagement.resourcemanager.impl.state.InstanceState;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@RunWith(MyContainerTestRunner.class)
|
||||
public class ServiceStartupTest {
|
||||
|
||||
@Deployment
|
||||
static Gar serviceGar = SERVICE_GAR();
|
||||
|
||||
public static Logger log = LoggerFactory.getLogger("test");
|
||||
|
||||
|
||||
@Inject
|
||||
static MyContainer container;
|
||||
|
||||
@Test
|
||||
public void serviceStartsUp() {
|
||||
|
||||
serviceIsReady();
|
||||
|
||||
binderIsReadyInRIScopes();
|
||||
|
||||
stateIsCreated();
|
||||
}
|
||||
|
||||
|
||||
// helper
|
||||
static void binderIsReadyInRIScopes() {
|
||||
//InstanceState binderResource = InstanceState..getContext().binder();
|
||||
//assertNotNull(binderResource);
|
||||
//Set<String> ghnScopes = ServiceContext.getContext().getInstance()
|
||||
// .getScopes().keySet();
|
||||
//Set<String> binderScopes = new HashSet<String>(binderResource.getResourcePropertySet().getScope());
|
||||
//assertEquals(ghnScopes, binderScopes);
|
||||
//log.info("T-Binder is instantiated and in RI scopes");
|
||||
}
|
||||
|
||||
public static void serviceIsReady() {
|
||||
assertTrue(ServiceContext.getContext().getStatus() == Status.READIED);
|
||||
log.info("service is ready");
|
||||
}
|
||||
|
||||
public static void stateIsCreated() {
|
||||
|
||||
}
|
||||
|
||||
public static Gar SERVICE_GAR() {
|
||||
return new Gar("resourcemanager").addInterfaces("../wsdl").addConfigurations("../config");
|
||||
}
|
||||
}
|
||||
|
|
@ -40,4 +40,7 @@
|
|||
</xs:schema>
|
||||
</types>
|
||||
|
||||
<portType name="VREManagementTypesPortType" >
|
||||
|
||||
</portType>
|
||||
</definitions>
|
||||
|
|
Loading…
Reference in New Issue