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