1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps.assertions.basic;
14
15 import java.util.HashMap;
16 import java.util.Map;
17
18 import org.apache.xmlbeans.XmlObject;
19
20 import com.eviware.soapui.config.TestAssertionConfig;
21 import com.eviware.soapui.impl.rest.RestResource;
22 import com.eviware.soapui.impl.rest.RestService;
23 import com.eviware.soapui.impl.support.AbstractInterface;
24 import com.eviware.soapui.impl.support.DefinitionContext;
25 import com.eviware.soapui.impl.wadl.WadlDefinitionContext;
26 import com.eviware.soapui.impl.wadl.support.WadlValidator;
27 import com.eviware.soapui.impl.wsdl.WsdlInterface;
28 import com.eviware.soapui.impl.wsdl.WsdlOperation;
29 import com.eviware.soapui.impl.wsdl.submit.RestMessageExchange;
30 import com.eviware.soapui.impl.wsdl.submit.WsdlMessageExchange;
31 import com.eviware.soapui.impl.wsdl.support.PathUtils;
32 import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
33 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
34 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlValidator;
35 import com.eviware.soapui.impl.wsdl.teststeps.WsdlMessageAssertion;
36 import com.eviware.soapui.impl.wsdl.teststeps.assertions.AbstractTestAssertionFactory;
37 import com.eviware.soapui.model.iface.MessageExchange;
38 import com.eviware.soapui.model.iface.SubmitContext;
39 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
40 import com.eviware.soapui.model.testsuite.Assertable;
41 import com.eviware.soapui.model.testsuite.AssertionError;
42 import com.eviware.soapui.model.testsuite.AssertionException;
43 import com.eviware.soapui.model.testsuite.RequestAssertion;
44 import com.eviware.soapui.model.testsuite.ResponseAssertion;
45 import com.eviware.soapui.model.testsuite.TestCaseRunContext;
46 import com.eviware.soapui.model.testsuite.TestCaseRunner;
47 import com.eviware.soapui.support.StringUtils;
48 import com.eviware.soapui.support.UISupport;
49 import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
50 import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
51
52 /***
53 * Asserts that a request or response message complies with its related WSDL
54 * definition / XML Schema
55 *
56 * @author Ole.Matzura
57 */
58
59 public class SchemaComplianceAssertion extends WsdlMessageAssertion implements RequestAssertion, ResponseAssertion
60 {
61 public static final String ID = "Schema Compliance";
62 public static final String LABEL = "Schema Compliance";
63
64 private String definition;
65 private DefinitionContext<?> definitionContext;
66 private String wsdlContextDef;
67 private static Map<String, WsdlContext> wsdlContextMap = new HashMap<String, WsdlContext>();
68 private static final String SCHEMA_COMPLIANCE_HAS_CLEARED_CACHE_FLAG = SchemaComplianceAssertion.class.getName()
69 + "@SchemaComplianceHasClearedCacheFlag";
70
71 public SchemaComplianceAssertion( TestAssertionConfig assertionConfig, Assertable assertable )
72 {
73 super( assertionConfig, assertable, false, true, false, true );
74
75 XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader( getConfiguration() );
76 definition = reader.readString( "definition", null );
77 }
78
79 @Override
80 public void prepare( TestCaseRunner testRunner, TestCaseRunContext testRunContext ) throws Exception
81 {
82 super.prepare( testRunner, testRunContext );
83
84 definitionContext = null;
85 wsdlContextDef = null;
86
87
88 PropertyExpansionContext context = testRunContext.hasProperty( TestCaseRunContext.LOAD_TEST_CONTEXT ) ? ( PropertyExpansionContext )testRunContext
89 .getProperty( TestCaseRunContext.LOAD_TEST_CONTEXT )
90 : testRunContext;
91
92 synchronized( context )
93 {
94 if( !context.hasProperty( SCHEMA_COMPLIANCE_HAS_CLEARED_CACHE_FLAG ) )
95 {
96 wsdlContextMap.clear();
97 context.setProperty( SCHEMA_COMPLIANCE_HAS_CLEARED_CACHE_FLAG, "yep!" );
98 }
99 }
100 }
101
102 protected String internalAssertResponse( MessageExchange messageExchange, SubmitContext context )
103 throws AssertionException
104 {
105 if( messageExchange instanceof WsdlMessageExchange )
106 {
107 return assertWsdlResponse( ( WsdlMessageExchange )messageExchange, context );
108 }
109 else if( messageExchange instanceof RestMessageExchange )
110 {
111 return assertWadlResponse( ( RestMessageExchange )messageExchange, context );
112 }
113
114 throw new AssertionException( new AssertionError( "Unknown MessageExchange type" ) );
115 }
116
117 private String assertWadlResponse( RestMessageExchange messageExchange, SubmitContext context )
118 throws AssertionException
119 {
120 WadlDefinitionContext wadlContext = null;
121 try
122 {
123 definitionContext = getWadlContext( messageExchange, context );
124 }
125 catch( Exception e1 )
126 {
127 throw new AssertionException( new AssertionError( e1.getMessage() ) );
128 }
129
130 WadlValidator validator = new WadlValidator( wadlContext );
131
132 try
133 {
134 AssertionError[] errors = validator.assertResponse( messageExchange );
135 if( errors.length > 0 )
136 throw new AssertionException( errors );
137 }
138 catch( AssertionException e )
139 {
140 throw e;
141 }
142 catch( Exception e )
143 {
144 throw new AssertionException( new AssertionError( e.getMessage() ) );
145 }
146
147 return "Schema compliance OK";
148 }
149
150 private String assertWsdlResponse( WsdlMessageExchange messageExchange, SubmitContext context )
151 throws AssertionException
152 {
153 WsdlContext wsdlContext = null;
154 try
155 {
156 wsdlContext = ( WsdlContext )getWsdlContext( messageExchange, context );
157 }
158 catch( Exception e1 )
159 {
160 throw new AssertionException( new AssertionError( e1.getMessage() ) );
161 }
162
163 WsdlValidator validator = new WsdlValidator( wsdlContext );
164
165 try
166 {
167 AssertionError[] errors = validator.assertResponse( messageExchange, false );
168 if( errors.length > 0 )
169 throw new AssertionException( errors );
170 }
171 catch( AssertionException e )
172 {
173 throw e;
174 }
175 catch( Exception e )
176 {
177 throw new AssertionException( new AssertionError( e.getMessage() ) );
178 }
179
180 return "Schema compliance OK";
181 }
182
183 private DefinitionContext<?> getWsdlContext( WsdlMessageExchange messageExchange, SubmitContext context )
184 throws Exception
185 {
186 WsdlOperation operation = messageExchange.getOperation();
187 WsdlInterface iface = operation.getInterface();
188 if( StringUtils.isNullOrEmpty( definition ) || definition.equals( iface.getDefinition() ) )
189 {
190 definitionContext = ( iface ).getWsdlContext();
191 ( ( WsdlContext )definitionContext ).loadIfNecessary();
192 }
193 else
194 {
195 String def = PathUtils.expandPath( definition, iface, context );
196 if( definitionContext == null || !def.equals( wsdlContextDef ) )
197 {
198 definitionContext = getContext( def, iface.getSoapVersion() );
199
200 ( ( WsdlContext )definitionContext ).setInterface( iface );
201 wsdlContextDef = def;
202 }
203 }
204
205 return definitionContext;
206 }
207
208 private synchronized WsdlContext getContext( String wsdlLocation, SoapVersion soapVersion ) throws Exception
209 {
210 if( wsdlContextMap.containsKey( wsdlLocation ) )
211 {
212 return wsdlContextMap.get( wsdlLocation );
213 }
214 else
215 {
216 WsdlContext newWsdlContext = new WsdlContext( wsdlLocation, soapVersion );
217 newWsdlContext.load();
218 wsdlContextMap.put( wsdlLocation, newWsdlContext );
219 return newWsdlContext;
220 }
221 }
222
223 private DefinitionContext<?> getWadlContext( RestMessageExchange messageExchange, SubmitContext context )
224 throws Exception
225 {
226 RestResource operation = messageExchange.getResource();
227 RestService service = operation.getService();
228 if( StringUtils.isNullOrEmpty( definition )
229 || definition.equals( PathUtils.expandPath( service.getDefinition(), service, context ) ) )
230 {
231 definitionContext = service.getWadlContext();
232 ( ( WadlDefinitionContext )definitionContext ).loadIfNecessary();
233 }
234 else
235 {
236 String def = PathUtils.expandPath( definition, service, context );
237 if( definitionContext == null || !def.equals( wsdlContextDef ) )
238 {
239 definitionContext = new WadlDefinitionContext( def );
240 ( ( WadlDefinitionContext )definitionContext ).load();
241 ( ( WadlDefinitionContext )definitionContext ).setInterface( service );
242 wsdlContextDef = def;
243 }
244 }
245
246 return definitionContext;
247 }
248
249 public boolean configure()
250 {
251 String value = definition;
252
253 AbstractInterface<?> iface = ( AbstractInterface<?> )getAssertable().getInterface();
254 String orgDef = iface == null ? null : iface.getDefinition();
255
256 if( StringUtils.isNullOrEmpty( value ) )
257 {
258 value = orgDef;
259 }
260
261 value = UISupport.prompt( "Specify definition url to validate by", "Configure SchemaCompliance Assertion", value );
262
263 if( value == null )
264 return false;
265
266 if( StringUtils.isNullOrEmpty( value ) || value.equals( orgDef ) )
267 definition = "";
268 else
269 definition = value;
270
271 setConfiguration( createConfiguration() );
272 return true;
273 }
274
275 protected XmlObject createConfiguration()
276 {
277 XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
278 return builder.add( "definition", definition ).finish();
279 }
280
281 protected String internalAssertRequest( MessageExchange messageExchange, SubmitContext context )
282 throws AssertionException
283 {
284 WsdlContext wsdlContext = null;
285 try
286 {
287 wsdlContext = ( WsdlContext )getWsdlContext( ( WsdlMessageExchange )messageExchange, context );
288 }
289 catch( Exception e1 )
290 {
291 throw new AssertionException( new AssertionError( e1.getMessage() ) );
292 }
293 WsdlValidator validator = new WsdlValidator( wsdlContext );
294
295 try
296 {
297 AssertionError[] errors = validator.assertRequest( ( WsdlMessageExchange )messageExchange, false );
298 if( errors.length > 0 )
299 throw new AssertionException( errors );
300 }
301 catch( AssertionException e )
302 {
303 throw e;
304 }
305 catch( Exception e )
306 {
307 throw new AssertionException( new AssertionError( e.getMessage() ) );
308 }
309
310 return "Schema compliance OK";
311 }
312
313 public static class Factory extends AbstractTestAssertionFactory
314 {
315 public Factory()
316 {
317 super( SchemaComplianceAssertion.ID, SchemaComplianceAssertion.LABEL, SchemaComplianceAssertion.class );
318 }
319
320 @Override
321 public boolean canAssert( Assertable assertable )
322 {
323 return super.canAssert( assertable ) && assertable.getInterface() instanceof AbstractInterface
324 && ( ( AbstractInterface<?> )assertable.getInterface() ).getDefinitionContext().hasSchemaTypes();
325 }
326 }
327 }