My use case warrants the use of a publish-subscribe model, so I'm using topics that are defined in my Spring Boot client. I've used the tool MQTT.fx and two Spring Boot clients to test things. The two Spring Boot clients are able to communicate with each other, but the MQTT.fx client only connects to the broker and does not produce or consume messages. The two Spring Boot clients both connect to port 61616, and the MQTT.fx client connects to port 1883.
For my project, I need to get the MQTT.fx client working as it is highly representative of the microcontroller that is intended to work with the server. Failure on MQTT.fx is failure on the microcontroller.
The acceptor configuration in my broker.xml file is as show below.
<acceptors>
<!-- Acceptor for every supported protocol -->
<acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;supportAdvisory=false;suppressInternalManagementObjects=false</acceptor>
<!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic.-->
<acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpMinLargeMessageSize=102400;amqpDuplicateDetection=true</acceptor>
<!-- STOMP Acceptor. -->
<acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>
<!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
<acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>
<!-- MQTT Acceptor -->
<acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>
</acceptors>
The logs when the Spring Boot clients communicate are as below. First, a message is sent to the topic server.weatherForecast, and consequently, after some processing, a response is sent to AMEBAA000105.device.weatherForecast.
2021-10-04 14:14:04,860 [AUDIT](Thread-8 (activemq-netty-threads))
AMQ601715: User admin(admins)#127.0.0.1:1125 successfully authenticated
2021-10-04 14:14:04,860 [AUDIT](Thread-8 (activemq-netty-threads)) AMQ601267: User admin(admins)#127.0.0.1:1125 is creating a core session on target resource ActiveMQServerImpl::name=0.0.0.0 [with parameters: [3b141c41-24ef-11ec-aa52-00155d831300, null, ****, 102400, RemotingConnectionImpl [ID=6280c69f, clientID=null, nodeID=b719c384-1d0a-11ec-8b7c-00155d831300, transportConnection=org.apache.activemq.artemis.core.remoting.impl.netty.NettyServerConnection#417b6fef[ID=6280c69f, local= /127.0.0.1:61616, remote=/127.0.0.1:1125]], true, true, false, false, null, org.apache.activemq.artemis.core.protocol.core.impl.CoreSessionCallback#103d417f, true, OperationContextImpl [61828916] [minimalStore=9223372036854775807, storeLineUp=0, stored=0, minimalReplicated=9223372036854775807, replicationLineUp=0, replicated=0, paged=0, minimalPage=9223372036854775807, pageLineUp=0, errorCode=-1, errorMessage=null, executorsPending=0, executor=OrderedExecutor(tasks=[])], {}]]
2021-10-04 14:14:04,864 [AUDIT](Thread-7 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$6#b62d79)) AMQ601500: User admin(admins)#127.0.0.1:1125 is sending a message CoreMessage[messageID=528267,durable=true,userID=3b146a62-24ef-11ec-aa52-00155d831300,priority=4, timestamp=Mon Oct 04 14:14:04 IST 2021,expiration=0, durable=true, address=jms.topic.server.weatherForecast,size=314,properties=TypedProperties[__AMQ_CID=3b13ce1f-24ef-11ec-aa52-00155d831300]]#1994364957, with Context: RoutingContextImpl(Address=null, routingType=null, PreviousAddress=null previousRoute:null, reusable=null, version=0)
..................................................
2021-10-04 14:14:04,865 [AUDIT](Thread-7 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$6#b62d79)) AMQ601501: User admin(admins)#127.0.0.1:1110 is consuming a message from 41207748-6ed3-42d2-b75e-044805212686: Reference[528267]:RELIABLE:CoreMessage[messageID=528267,durable=true,userID=3b146a62-24ef-11ec-aa52-00155d831300,priority=4, timestamp=Mon Oct 04 14:14:04 IST 2021,expiration=0, durable=true, address=jms.topic.server.weatherForecast,size=314,properties=TypedProperties[__AMQ_CID=3b13ce1f-24ef-11ec-aa52-00155d831300]]#1994364957
2021-10-04 14:14:04,868 [AUDIT](Thread-4 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$6#b62d79)) AMQ601502: User admin(admins)#127.0.0.1:1110 is acknowledging a message from 41207748-6ed3-42d2-b75e-044805212686: CoreMessage[messageID=528267,durable=true,userID=3b146a62-24ef-11ec-aa52-00155d831300,priority=4, timestamp=Mon Oct 04 14:14:04 IST 2021,expiration=0, durable=true, address=jms.topic.server.weatherForecast,size=314,properties=TypedProperties[__AMQ_CID=3b13ce1f-24ef-11ec-aa52-00155d831300]]#1994364957
2021-10-04 14:14:08,059 [AUDIT](Thread-8 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$6#b62d79)) AMQ601500: User admin(admins)#127.0.0.1:1110 is sending a message CoreMessage[messageID=528349,durable=true,userID=3cfc1623-24ef-11ec-aa52-00155d831300,priority=4, timestamp=Mon Oct 04 14:14:08 IST 2021,expiration=0, durable=true, address=null,size=190,properties=TypedProperties[__AMQ_CID=d04d0e87-24ee-11ec-aa52-00155d831300]]#600964226, with Context: RoutingContextImpl(Address=jms.topic.AMEBAA000105.device.weatherForecast, routingType=null, PreviousAddress=jms.topic.AMEBAA000105.device.weatherForecast previousRoute:null, reusable=null, version=0)
..................................................
The logs when using MQTT.fx are as below. Initially AMEBAA000105.device.weatherForecast is subscribed to, and then a message is sent to server.weatherForecast. The Spring Boot client meant to receive these messages does not receive anything, and consequently does not send anything to AMEBAA000105.device.weatherForecast. When the publication of a message to AMEBAA000105.device.weatherForecast from the Spring Boot client is triggered by another Spring Boot client, MQTT.fx does not capture the message.
2021-10-04 14:24:35,443 [AUDIT](Thread-17 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$6#b62d79)) AMQ601265: User admin(admins)#192.168.0.107:18640 is creating a core consumer on target resource ServerSessionImpl() [with parameters: [534062, MQTT_FX_Client.AMEBAA000105.device.weatherForecast, null, 0, false, false, -1]]
2021-10-04 14:24:43,719 [AUDIT](Thread-10 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$6#b62d79)) AMQ601500: User admin(admins)#192.168.0.107:18640 is sending a message CoreMessage[messageID=534380,durable=false,userID=null,priority=0, timestamp=0,expiration=0, durable=false, address=server.weatherForecast,size=200,properties=TypedProperties[mqtt.message.retain=false,mqtt.qos.level=0]]#1214406991, with Context: RoutingContextImpl(Address=server.weatherForecast, routingType=null, PreviousAddress=null previousRoute:null, reusable=null, version=0)
The above logs are the audit logs. In the artemis.log file, MQTT.fx keeps pinging the broker.
2021-10-04 14:30:43,727 TRACE [org.apache.activemq.artemis.core.protocol.mqtt] MQTT(MQTT_FX_Client): OUT >> PINGRESP
2021-10-04 14:31:43,728 TRACE [org.apache.activemq.artemis.core.protocol.mqtt] MQTT(MQTT_FX_Client): OUT >> PINGRESP
2021-10-04 14:32:43,729 TRACE [org.apache.activemq.artemis.core.protocol.mqtt] MQTT(MQTT_FX_Client): OUT >> PINGRESP
2021-10-04 14:33:43,731 TRACE [org.apache.activemq.artemis.core.protocol.mqtt] MQTT(MQTT_FX_Client): OUT >> PINGRESP
2021-10-04 14:34:43,732 TRACE [org.apache.activemq.artemis.core.protocol.mqtt] MQTT(MQTT_FX_Client): OUT >> PINGRESP
2021-10-04 14:35:43,733 TRACE [org.apache.activemq.artemis.core.protocol.mqtt] MQTT(MQTT_FX_Client): OUT >> PINGRESP
Logs when subscribing or publishing from MQTT.fx in the artemis.log file are as below
2021-10-04 14:22:27,702 TRACE [org.apache.activemq.artemis.core.protocol.mqtt] MQTT(MQTT_FX_Client): IN << SUBSCRIBE(3)
AMEBAA000105.device.weatherForecast : AT_MOST_ONCE
2021-10-04 14:24:43,718 TRACE [org.apache.activemq.artemis.core.protocol.mqtt] MQTT(MQTT_FX_Client): IN << PUBLISH(-1) topic=server.weatherForecast, qos=AT_MOST_ONCE, retain=false, dup=false, payload={"serialNumber" : "AMEBAA000105"}
Any help is much appreciated.
You say that when you're testing the Spring Boot clients you send a message to server.weatherForecast and the after some processing a response is sent to AMEBAA000105.device.weatherForecast. However, that is not what the logs show. The logs indicate that you send a message to jms.topic.server.weatherForecast and jms.topic.AMEBAA000105.device.weatherForecast respectively. Notice the jms.topic. prefix.
I believe this is the root of your problem because according to the logs the MQTT actually will use server.weatherForecast and AMEBAA000105.device.weatherForecast. Since the two clients aren't using matching names then they can never work together with your current configuration.
My guess is that you're using a legacy Artemis 1.x client from your Spring Boot applications and that is why the jms.topic. prefix is being used. You should either move to a newer client (e.g. one that matches the broker version you're using) or configure the anycastPrefix and multicastPrefix to support the legacy 1.x client. The default broker.xml has a comment which explains how to do this:
<!-- Note: If an acceptor needs to be compatible with HornetQ and/or Artemis 1.x clients add
"anycastPrefix=jms.queue.;multicastPrefix=jms.topic." to the acceptor url.
See https://issues.apache.org/jira/browse/ARTEMIS-1644 for more information. -->
This comment appears in the acceptors block by default, but it looks like you removed it since it's not in the XML you pasted.
If you want to confirm which library the client is using the simplest way to to find out is simply to inspect the client's environment. However, if that doesn't work and you have access to the broker logs then you can enable TRACE logging for org.apache.activemq.artemis.core.protocol.core.impl.RemotingConnectionImpl and then look at the version passed in the CreateSessionMessage. If it's < 131 then it's not a 2.18.0 client.
Changing the signature of consumeWeatherForecastRequest method to private void consumeWeatherForecastRequest(String incomingMessage) should fix your issue.
I have a profile adapter using https://randomuser.me/ API
adapter.xml
<wl:adapter name="comradeAdapter"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wl="http://www.ibm.com/mfp/integration"
xmlns:http="http://www.ibm.com/mfp/integration/http">
<displayName>comradeAdapter</displayName>
<description>comradeAdapter</description>
<connectivity>
<connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
<protocol>https</protocol>
<domain>api.randomuser.me</domain>
<port>443</port>
<connectionTimeoutInMilliseconds>30000</connectionTimeoutInMilliseconds>
<socketTimeoutInMilliseconds>30000</socketTimeoutInMilliseconds>
<maxConcurrentConnectionsPerNode>50</maxConcurrentConnectionsPerNode>
<!-- Following properties used by adapter's key manager for choosing specific certificate from key store
<sslCertificateAlias></sslCertificateAlias>
<sslCertificatePassword></sslCertificatePassword>
-->
</connectionPolicy>
</connectivity>
<procedure name="getFeed"/>
</wl:adapter>
comradeAdapter.js
function getFeed() {
path = '?results=20';
var input = {
method : 'get',
returnedContentType : 'json',
path : path
};
return WL.Server.invokeHttp(input);
}
On my local, I can invoke data successfully. But when I deploy to mobilefirst console server 8.0 which is provided by ibm bluemix, I cannot get data on Swagger:
Request URL
https://mydemo-tac-ha-server.mybluemix.net/mfp/api/adapters/comradeAdapter/getFeed
Response Body
no content
Response Code
401
Response Headers
{
"x-backside-transport": "FAIL FAIL",
"connection": "Keep-Alive",
"transfer-encoding": "chunked",
"date": "Mon, 12 Sep 2016 10:15:57 GMT",
"www-authenticate": "Bearer",
"x-powered-by": "Servlet/3.1",
"x-global-transaction-id": "3044026435",
"content-type": null
}
Please hele me review and give me your thoughts to can get data from server mfp 8.0
To migrate existing adapters and applications to MobileFirst Foundation 8.0 there are the following materials:
Cookbook: https://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/8.0/migration-cookbook/
Example application migration: https://mobilefirstplatform.ibmcloud.com/labs/developers/8.0/advancedwallet/
I am trying to make a chat application with WebSocket. I am able to send a message to all the connected clients, and now I am trying to send a message to a single user.
script:
var socket = new SockJS("server endpoint");
subscribe:
stompClient.subscribe('/topic/chat', renderMessage);
connection:
stompClient.connect("guest", "guest", connectCallback, errorCallback);
where it's sent:
stompClient.send("/app/addMessage", {}, jsonstr);
and in my spring config:
<websocket:message-broker
application-destination-prefix="/app">
<websocket:stomp-endpoint path="/ws">
<websocket:sockjs />
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic" />
<websocket:client-inbound-channel>
<websocket:interceptors>
<bean class="com.websocket.interceptor.ConnectionInterceptor" />
</websocket:interceptors>
</websocket:client-inbound-channel>
</websocket:message-broker>
method that is trying to send to a single user:
#MessageMapping("/addMessage")
public void addChatMessage(ChatMessage chatMessage,
SimpMessageHeaderAccessor headerAccessor,Principal principal) throws Exception {
chatMessageList.add(chatMessage);
//trying to output the user but returns null
System.out.println(headerAccessor.getUser());
//returns null
System.out.println(principal.getName());
//not sending to the current user
template.convertAndSendToUser("user", "/topic/chat", chatMessageList);
}
and in my browser, I tried to open the console and I can see that the header is undefined:
connected to server undefined
>>> SUBSCRIBE
id:sub-0
destination:/topic/chat
stack trace:
Oct 13, 2014 9:53:36 AM org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler processHandlerMethodException
SEVERE: Unhandled exception
org.springframework.messaging.simp.annotation.support.MissingSessionUserException: No "user" header in message
at org.springframework.messaging.simp.annotation.support.PrincipalMethodArgumentResolver.resolveArgument(PrincipalMethodArgumentResolver.java:43)
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:81)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:128)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:97)
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:451)
at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:363)
at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:80)
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:409)
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:345)
at org.springframework.messaging.support.ExecutorSubscribableChannel$1.run(ExecutorSubscribableChannel.java:70)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
How can I send to a single user? How can I get all the headers in my SimpMessageHeaderAccessor? And how headers actually work?
When you subscribe you need to use "/user/" prefix to make it recognized by Spring UserDestinationMessageHandler. So the code will be :
stompClient.subscribe('user/topic/chat', renderMessage);
See Spring Websocket user destinations.
while implementing a SSL-secured WebService with Apache CXF v2.7.3 I wanted to test how a custom exception class (e.g. MyException) is handled by the client.
Therefore I have the following server-side method:
#WebMethod
public void foo() throws MyException {
throw new MyException("test!");
}
I have also configured to log in- and outgoing messages in the cxf.xml via:
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<jaxws:inInterceptors>
<ref bean="logInbound"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="logOutbound"/>
</jaxws:outInterceptors>
Calling this function with a client results in following console-output
INFO: Inbound Message
----------------------------
ID: 1
Address: https://localhost:8443/WebApp/services/ClientService
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[184], content-type=[text/xml; charset=UTF-8], host=[localhost:8443], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 2.7.3]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:foo xmlns:ns2="http://services.client.test.cloud.org/"/></soap:Body></soap:Envelope>
--------------------------------------
18.02.2013 22:49:02 org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
INFO: Application {http://services.client.test.cloud.org/}ClientService#{http://services.client.test.cloud.org/}foo has thrown exception, unwinding now: org.cloud.test.client.exception.MyException: test!
18.02.2013 22:49:02 org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
INFO: Application {http://services.client.test.cloud.org/}ClientService#{http://services.client.test.cloud.org/}foo has thrown exception, unwinding now: java.lang.NullPointerException: null
The client gets a "Error reading XMLStreamReader." due to a "Unexpected EOF". I guess, that no response is written by the server. Do you know why 2 exceptions are thrown and why there isn't any response to the client?
I already searched for exceptions not redirected to the client in Apache CXF-applications, but could not find any solution.
Thanks in advance!
i am writing a small java client that uses the Azure Service Management API to create a new VM Deployment on Azure.
i keep getting bad requests responses like these:
17/07/2012 18:26:37 com.sun.jersey.api.client.filter.LoggingFilter log
INFO: 1 * Client out-bound request
1 > POST https://management.core.windows.net/my-subscription-id/services/hostedservices/myservice/deployments
1 > x-ms-version: 2012-03-01
1 > Content-Type: application/xml
<Deployment xmlns="http://schemas.microsoft.com/windowsazure">
<Name>mynametest</Name>
<DeploymentSlot>Staging</DeploymentSlot>
<Label>mynamelabel</Label>
<RoleList>
<Role>
<RoleName>mynamerolename</RoleName>
<RoleType>PersistentVMRole</RoleType>
<ConfigurationSets>
<ConfigurationSet>
<ConfigurationSetType>LinuxProvisioningConfiguration</ConfigurationSetType>
<HostName>myunamehost</HostName>
<UserName>myname</UserName>
<UserPassword>password</UserPassword>
</ConfigurationSet>
</ConfigurationSets>
<OSVirtualHardDisk>
<SourceImageName>CANONICAL__Canonical-Ubuntu-12-04-amd64-server-20120528.1.3-en-us-30GB.vhd</SourceImageName>
</OSVirtualHardDisk>
</Role>
</RoleList>
</Deployment>
17/07/2012 18:26:38 com.sun.jersey.api.client.filter.LoggingFilter log
INFO: 1 * Client in-bound response
1 < 400
1 < x-ms-request-id: c622e270c5934cb493f76790b7d2c49d
1 < Date: Tue, 17 Jul 2012 15:27:26 GMT
1 < Content-Length: 275
1 < Content-Type: application/xml; charset=utf-8
1 < Server: 6.0.6002.18488 (rd_rdfe_stable.120710-1331) Microsoft-HTTPAPI/2.0
1 <
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Code>BadRequest</Code><Message>No target URI is specified for the image CANONICAL__Canonical-Ubuntu-12-04-amd64-server-20120528.1.3-en-us-30GB.vhd.</Message></Error>
it looks like the docs from azure are buggy: http://msdn.microsoft.com/en-us/library/windowsazure/jj157194
anyone has tried this before? i dont understand what does 'target URI' mean...
the image name is taken from the public gallery of images on azure.
any help, any help at all, will be highly appreciated.
thanks
Your xml have some bad configuration i.e. DeploymentSlot etc and I also believe the error is coming because you do not have all required settings in your XML. Following is the working one for Linux Gallery image:
<Deployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Name>mydeploymentname</Name>
<Label>mydeploymentlabel</Label>
<RoleList>
<Role>
<RoleName>mylinuxvm2012</RoleName>
<RoleType>PersistentVMRole</RoleType>
<ConfigurationSets>
<ConfigurationSet>
<ConfigurationSetType>LinuxProvisioningConfiguration<ConfigurationSetType>
<HostName>host-name-for-the-vm</HostName>
<UserName>new-user-name</UserName>
<UserPassword>password-for-the-new-user</UserPassword>
<DisableSshPasswordAuthentication>true|false</DisableSshPasswordAuthentication>
<SSH>
<PublicKeys>
<PublicKey>
<FingerPrint>******add_here******</FingerPrint>
<Path>****SSH-public-key-storage-location**********</Path>
</PublicKey>
</PublicKeys>
<KeyPairs>
<KeyPair>
<FingerPrint>************certificate-fingerprint*************</FinguerPrint>
<Path>*************SSH-public-key-storage-location*************</Path>
</KeyPair>
</KeyPairs>
</SSH>
</ConfigurationSet>
<OSVirtualHardDisk>
<HostCaching>ReadWrite</HostCaching>
<DiskLabel>myosdisklabel</DiskLabel>
<DiskName>myazurelinuxvm</DiskName>
<MediaLink>https://_yourstoragename_.blob.core.windows.net/vhds/_your_VHD_NAME_.vhd</MediaLink>
<SourceImageName>CANONICAL__Canonical-Ubuntu-12-04-amd64-server-20120528.1.3-en-us-30GB.vhd</SourceImageName>
</OSVirtualHardDisk>
<RoleSize>_ExtraSmall|Small|Medium|Large|ExtraLarge_</RoleSize>
</Role>
</RoleList>