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