001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.ws.policy;
019:
020: import java.util.ArrayList;
021: import java.util.Collection;
022: import java.util.HashSet;
023: import java.util.List;
024: import java.util.Map;
025: import java.util.Set;
026: import java.util.concurrent.ConcurrentHashMap;
027:
028: import javax.annotation.PostConstruct;
029: import javax.xml.namespace.QName;
030:
031: import org.apache.cxf.Bus;
032: import org.apache.cxf.extension.BusExtension;
033: import org.apache.cxf.helpers.CastUtils;
034: import org.apache.cxf.service.model.BindingFaultInfo;
035: import org.apache.cxf.service.model.BindingMessageInfo;
036: import org.apache.cxf.service.model.BindingOperationInfo;
037: import org.apache.cxf.service.model.EndpointInfo;
038: import org.apache.cxf.service.model.ServiceInfo;
039: import org.apache.cxf.transport.Conduit;
040: import org.apache.cxf.transport.Destination;
041: import org.apache.cxf.ws.policy.selector.MinimalAlternativeSelector;
042: import org.apache.neethi.Assertion;
043: import org.apache.neethi.Constants;
044: import org.apache.neethi.Policy;
045: import org.apache.neethi.PolicyComponent;
046: import org.apache.neethi.PolicyOperator;
047: import org.apache.neethi.PolicyReference;
048: import org.apache.neethi.PolicyRegistry;
049:
050: /**
051: *
052: */
053: public class PolicyEngineImpl implements PolicyEngine, BusExtension {
054:
055: private Bus bus;
056: private PolicyRegistry registry;
057: private Collection<PolicyProvider> policyProviders;
058: private boolean enabled;
059: private boolean ignoreUnknownAssertions;
060: private boolean addedBusInterceptors;
061: private AlternativeSelector alternativeSelector;
062:
063: private Map<BindingOperation, EffectivePolicy> clientRequestInfo;
064:
065: private Map<BindingOperation, EffectivePolicy> clientResponseInfo;
066:
067: private Map<BindingFault, EffectivePolicy> clientFaultInfo;
068:
069: private Map<BindingOperation, EffectivePolicy> serverRequestInfo;
070:
071: private Map<BindingOperation, EffectivePolicy> serverResponseInfo;
072:
073: private Map<BindingFault, EffectivePolicy> serverFaultInfo;
074:
075: private Map<EndpointInfo, EndpointPolicy> endpointInfo;
076:
077: public PolicyEngineImpl() {
078: init();
079: }
080:
081: // configuration
082:
083: public boolean isEnabled() {
084: return enabled;
085: }
086:
087: public void setBus(Bus b) {
088: bus = b;
089: }
090:
091: public Bus getBus() {
092: return bus;
093: }
094:
095: public void setPolicyProviders(Collection<PolicyProvider> p) {
096: policyProviders = p;
097: }
098:
099: public Collection<PolicyProvider> getPolicyProviders() {
100: return policyProviders;
101: }
102:
103: public void setRegistry(PolicyRegistry r) {
104: registry = r;
105: }
106:
107: public PolicyRegistry getRegistry() {
108: return registry;
109: }
110:
111: public synchronized void setEnabled(boolean e) {
112: enabled = e;
113:
114: if (!addedBusInterceptors) {
115: addBusInterceptors();
116: }
117: }
118:
119: public AlternativeSelector getAlternativeSelector() {
120: return alternativeSelector;
121: }
122:
123: public void setAlternativeSelector(AlternativeSelector as) {
124: alternativeSelector = as;
125: }
126:
127: public boolean isIgnoreUnknownAssertions() {
128: return ignoreUnknownAssertions;
129: }
130:
131: public void setIgnoreUnknownAssertions(boolean ignore) {
132: ignoreUnknownAssertions = ignore;
133: }
134:
135: // BusExtension interface
136:
137: public Class<?> getRegistrationType() {
138: return PolicyEngine.class;
139: }
140:
141: // PolicyEngine interface
142:
143: public EffectivePolicy getEffectiveClientRequestPolicy(
144: EndpointInfo ei, BindingOperationInfo boi, Conduit c) {
145: BindingOperation bo = new BindingOperation(ei, boi);
146: EffectivePolicy effectivePolicy = clientRequestInfo.get(bo);
147: if (null == effectivePolicy) {
148: EffectivePolicyImpl epi = createOutPolicyInfo();
149: Assertor assertor = null;
150: if (c instanceof Assertor) {
151: assertor = (Assertor) c;
152: }
153: epi.initialise(ei, bo.getBindingOperation(), this ,
154: assertor, true);
155: clientRequestInfo.put(bo, epi);
156: effectivePolicy = epi;
157: }
158: return effectivePolicy;
159: }
160:
161: public void setEffectiveClientRequestPolicy(EndpointInfo ei,
162: BindingOperationInfo boi, EffectivePolicy ep) {
163: BindingOperation bo = new BindingOperation(ei, boi);
164: clientRequestInfo.put(bo, ep);
165: }
166:
167: public EffectivePolicy getEffectiveServerResponsePolicy(
168: EndpointInfo ei, BindingOperationInfo boi, Destination d) {
169: BindingOperation bo = new BindingOperation(ei, boi);
170: EffectivePolicy effectivePolicy = serverResponseInfo.get(bo);
171: if (null == effectivePolicy) {
172: EffectivePolicyImpl epi = createOutPolicyInfo();
173: Assertor assertor = null;
174: if (d instanceof Assertor) {
175: assertor = (Assertor) d;
176: }
177: epi.initialise(ei, bo.getBindingOperation(), this ,
178: assertor, false);
179: serverResponseInfo.put(bo, epi);
180: effectivePolicy = epi;
181: }
182: return effectivePolicy;
183: }
184:
185: public void setEffectiveServerResponsePolicy(EndpointInfo ei,
186: BindingOperationInfo boi, EffectivePolicy ep) {
187: BindingOperation bo = new BindingOperation(ei, boi);
188: serverResponseInfo.put(bo, ep);
189: }
190:
191: public EffectivePolicy getEffectiveServerFaultPolicy(
192: EndpointInfo ei, BindingFaultInfo bfi, Destination d) {
193: BindingFault bf = new BindingFault(ei, bfi);
194: EffectivePolicy effectivePolicy = serverFaultInfo.get(bf);
195: if (null == effectivePolicy) {
196: EffectivePolicyImpl epi = createOutPolicyInfo();
197: Assertor assertor = null;
198: if (d instanceof Assertor) {
199: assertor = (Assertor) d;
200: }
201: epi.initialise(ei, bfi, this , assertor);
202: serverFaultInfo.put(bf, epi);
203: effectivePolicy = epi;
204: }
205: return effectivePolicy;
206: }
207:
208: public void setEffectiveServerFaultPolicy(EndpointInfo ei,
209: BindingFaultInfo bfi, EffectivePolicy ep) {
210: BindingFault bf = new BindingFault(ei, bfi);
211: serverFaultInfo.put(bf, ep);
212: }
213:
214: public EndpointPolicy getClientEndpointPolicy(EndpointInfo ei,
215: Conduit conduit) {
216: EndpointPolicy endpointPolicy = endpointInfo.get(ei);
217: if (null != endpointPolicy) {
218: return endpointPolicy;
219: }
220: Assertor assertor = conduit instanceof Assertor ? (Assertor) conduit
221: : null;
222: return createEndpointPolicyInfo(ei, true, assertor);
223: }
224:
225: public EndpointPolicy getServerEndpointPolicy(EndpointInfo ei,
226: Destination destination) {
227: EndpointPolicy endpointPolicy = endpointInfo.get(ei);
228: if (null != endpointPolicy) {
229: return endpointPolicy;
230: }
231: Assertor assertor = destination instanceof Assertor ? (Assertor) destination
232: : null;
233: return createEndpointPolicyInfo(ei, false, assertor);
234: }
235:
236: public void setEndpointPolicy(EndpointInfo ei, EndpointPolicy ep) {
237: endpointInfo.put(ei, ep);
238: }
239:
240: public EffectivePolicy getEffectiveServerRequestPolicy(
241: EndpointInfo ei, BindingOperationInfo boi) {
242: BindingOperation bo = new BindingOperation(ei, boi);
243: EffectivePolicy effectivePolicy = serverRequestInfo.get(bo);
244: if (null == effectivePolicy) {
245: EffectivePolicyImpl epi = createOutPolicyInfo();
246: epi.initialisePolicy(ei, bo.getBindingOperation(), this ,
247: false);
248: serverRequestInfo.put(bo, epi);
249: effectivePolicy = epi;
250: }
251: return effectivePolicy;
252: }
253:
254: public void setEffectiveServerRequestPolicy(EndpointInfo ei,
255: BindingOperationInfo boi, EffectivePolicy ep) {
256: BindingOperation bo = new BindingOperation(ei, boi);
257: serverRequestInfo.put(bo, ep);
258: }
259:
260: public EffectivePolicy getEffectiveClientResponsePolicy(
261: EndpointInfo ei, BindingOperationInfo boi) {
262: BindingOperation bo = new BindingOperation(ei, boi);
263: EffectivePolicy effectivePolicy = clientResponseInfo.get(bo);
264: if (null == effectivePolicy) {
265: EffectivePolicyImpl epi = createOutPolicyInfo();
266: epi.initialisePolicy(ei, bo.getBindingOperation(), this ,
267: true);
268: clientResponseInfo.put(bo, epi);
269: effectivePolicy = epi;
270: }
271: return effectivePolicy;
272: }
273:
274: public void setEffectiveClientResponsePolicy(EndpointInfo ei,
275: BindingOperationInfo boi, EffectivePolicy ep) {
276: BindingOperation bo = new BindingOperation(ei, boi);
277: clientResponseInfo.put(bo, ep);
278: }
279:
280: public EffectivePolicy getEffectiveClientFaultPolicy(
281: EndpointInfo ei, BindingFaultInfo bfi) {
282: BindingFault bf = new BindingFault(ei, bfi);
283: EffectivePolicy effectivePolicy = clientFaultInfo.get(bf);
284: if (null == effectivePolicy) {
285: EffectivePolicyImpl epi = createOutPolicyInfo();
286: epi.initialisePolicy(ei, bfi, this );
287: clientFaultInfo.put(bf, epi);
288: effectivePolicy = epi;
289: }
290: return effectivePolicy;
291: }
292:
293: public void setEffectiveClientFaultPolicy(EndpointInfo ei,
294: BindingFaultInfo bfi, EffectivePolicy ep) {
295: BindingFault bf = new BindingFault(ei, bfi);
296: clientFaultInfo.put(bf, ep);
297: }
298:
299: // implementation
300:
301: protected final void init() {
302:
303: registry = new PolicyRegistryImpl();
304:
305: clientRequestInfo = new ConcurrentHashMap<BindingOperation, EffectivePolicy>();
306:
307: clientResponseInfo = new ConcurrentHashMap<BindingOperation, EffectivePolicy>();
308:
309: clientFaultInfo = new ConcurrentHashMap<BindingFault, EffectivePolicy>();
310:
311: endpointInfo = new ConcurrentHashMap<EndpointInfo, EndpointPolicy>();
312:
313: serverRequestInfo = new ConcurrentHashMap<BindingOperation, EffectivePolicy>();
314:
315: serverResponseInfo = new ConcurrentHashMap<BindingOperation, EffectivePolicy>();
316:
317: serverFaultInfo = new ConcurrentHashMap<BindingFault, EffectivePolicy>();
318: }
319:
320: @PostConstruct
321: public void addBusInterceptors() {
322:
323: if (null == alternativeSelector) {
324: alternativeSelector = new MinimalAlternativeSelector();
325: }
326:
327: if (null == bus || !enabled) {
328: return;
329: }
330:
331: AssertionBuilderRegistry abr = bus
332: .getExtension(AssertionBuilderRegistry.class);
333: if (null != abr) {
334: abr.setIgnoreUnknownAssertions(ignoreUnknownAssertions);
335: }
336:
337: ClientPolicyOutInterceptor clientOut = new ClientPolicyOutInterceptor();
338: clientOut.setBus(bus);
339: bus.getOutInterceptors().add(clientOut);
340: ClientPolicyInInterceptor clientIn = new ClientPolicyInInterceptor();
341: clientIn.setBus(bus);
342: bus.getInInterceptors().add(clientIn);
343: ClientPolicyInFaultInterceptor clientInFault = new ClientPolicyInFaultInterceptor();
344: clientInFault.setBus(bus);
345: bus.getInFaultInterceptors().add(clientInFault);
346:
347: ServerPolicyInInterceptor serverIn = new ServerPolicyInInterceptor();
348: serverIn.setBus(bus);
349: bus.getInInterceptors().add(serverIn);
350: ServerPolicyOutInterceptor serverOut = new ServerPolicyOutInterceptor();
351: serverOut.setBus(bus);
352: bus.getOutInterceptors().add(serverOut);
353: ServerPolicyOutFaultInterceptor serverOutFault = new ServerPolicyOutFaultInterceptor();
354: serverOutFault.setBus(bus);
355: bus.getOutFaultInterceptors().add(serverOutFault);
356:
357: PolicyVerificationOutInterceptor verifyOut = new PolicyVerificationOutInterceptor();
358: verifyOut.setBus(bus);
359: bus.getOutInterceptors().add(verifyOut);
360: PolicyVerificationInInterceptor verifyIn = new PolicyVerificationInInterceptor();
361: verifyIn.setBus(bus);
362: bus.getInInterceptors().add(verifyIn);
363: PolicyVerificationInFaultInterceptor verifyInFault = new PolicyVerificationInFaultInterceptor();
364: verifyInFault.setBus(bus);
365: bus.getInFaultInterceptors().add(verifyInFault);
366:
367: addedBusInterceptors = true;
368: }
369:
370: Policy getAggregatedServicePolicy(ServiceInfo si) {
371: Policy aggregated = null;
372: for (PolicyProvider pp : getPolicyProviders()) {
373: Policy p = pp.getEffectivePolicy(si);
374: if (null == aggregated) {
375: aggregated = p;
376: } else if (p != null) {
377: aggregated = aggregated.merge(p);
378: }
379: }
380: return aggregated == null ? new Policy() : aggregated;
381: }
382:
383: Policy getAggregatedEndpointPolicy(EndpointInfo ei) {
384: Policy aggregated = null;
385: for (PolicyProvider pp : getPolicyProviders()) {
386: Policy p = pp.getEffectivePolicy(ei);
387: if (null == aggregated) {
388: aggregated = p;
389: } else if (p != null) {
390: aggregated = aggregated.merge(p);
391: }
392: }
393: return aggregated == null ? new Policy() : aggregated;
394: }
395:
396: Policy getAggregatedOperationPolicy(BindingOperationInfo boi) {
397: Policy aggregated = null;
398: for (PolicyProvider pp : getPolicyProviders()) {
399: Policy p = pp.getEffectivePolicy(boi);
400: if (null == aggregated) {
401: aggregated = p;
402: } else if (p != null) {
403: aggregated = aggregated.merge(p);
404: }
405: }
406: return aggregated == null ? new Policy() : aggregated;
407: }
408:
409: Policy getAggregatedMessagePolicy(BindingMessageInfo bmi) {
410: Policy aggregated = null;
411: for (PolicyProvider pp : getPolicyProviders()) {
412: Policy p = pp.getEffectivePolicy(bmi);
413: if (null == aggregated) {
414: aggregated = p;
415: } else if (p != null) {
416: aggregated = aggregated.merge(p);
417: }
418: }
419: return aggregated == null ? new Policy() : aggregated;
420: }
421:
422: Policy getAggregatedFaultPolicy(BindingFaultInfo bfi) {
423: Policy aggregated = null;
424: for (PolicyProvider pp : getPolicyProviders()) {
425: Policy p = pp.getEffectivePolicy(bfi);
426: if (null == aggregated) {
427: aggregated = p;
428: } else if (p != null) {
429: aggregated = aggregated.merge(p);
430: }
431: }
432: return aggregated == null ? new Policy() : aggregated;
433: }
434:
435: /**
436: * Return a collection of all assertions used in the given policy component,
437: * optionally including optional assertions.
438: * The policy need not be normalised, so any policy references will have to be resolved.
439: * @param pc the policy component
440: * @param includeOptional flag indicating if optional assertions should be included
441: * @return the assertions
442: */
443: Collection<Assertion> getAssertions(PolicyComponent pc,
444: boolean includeOptional) {
445:
446: Collection<Assertion> assertions = new ArrayList<Assertion>();
447:
448: if (Constants.TYPE_ASSERTION == pc.getType()) {
449: Assertion a = (Assertion) pc;
450: if (includeOptional || !a.isOptional()) {
451: assertions.add(a);
452: }
453: } else {
454: addAssertions(pc, includeOptional, assertions);
455: }
456: return assertions;
457: }
458:
459: void addAssertions(PolicyComponent pc, boolean includeOptional,
460: Collection<Assertion> assertions) {
461:
462: if (Constants.TYPE_ASSERTION == pc.getType()) {
463: Assertion a = (Assertion) pc;
464: if (includeOptional || !a.isOptional()) {
465: assertions.add((Assertion) pc);
466: }
467: return;
468: }
469:
470: if (Constants.TYPE_POLICY_REF == pc.getType()) {
471: PolicyReference pr = (PolicyReference) pc;
472: pc = pr.normalize(registry, false);
473: }
474:
475: PolicyOperator po = (PolicyOperator) pc;
476:
477: List<PolicyComponent> pcs = CastUtils.cast(po
478: .getPolicyComponents(), PolicyComponent.class);
479: for (PolicyComponent child : pcs) {
480: addAssertions(child, includeOptional, assertions);
481: }
482: }
483:
484: /**
485: * Return the vocabulary of a policy component, i.e. the set of QNames of
486: * the assertions used in the componente, duplicates removed.
487: * @param pc the policy component
488: * @param includeOptional flag indicating if optional assertions should be included
489: * @return the vocabulary
490: */
491: Set<QName> getVocabulary(PolicyComponent pc, boolean includeOptional) {
492: Collection<Assertion> assertions = getAssertions(pc,
493: includeOptional);
494: Set<QName> vocabulary = new HashSet<QName>();
495: for (Assertion a : assertions) {
496: vocabulary.add(a.getName());
497: }
498: return vocabulary;
499: }
500:
501: EndpointPolicyImpl createEndpointPolicyInfo(EndpointInfo ei,
502: boolean isRequestor, Assertor assertor) {
503: EndpointPolicyImpl epi = createEndpointPolicyInfo();
504: epi.initialise(ei, isRequestor, this , assertor);
505: endpointInfo.put(ei, epi);
506:
507: return epi;
508: }
509:
510: /**
511: * Check if a given list of assertions can potentially be supported by
512: * interceptors or by an already installed assertor (a conduit or transport
513: * that implements the Assertor interface).
514: *
515: * @param alternative the policy alternative
516: * @param Assertor the assertor
517: * @return true iff the alternative can be supported
518: */
519: public boolean supportsAlternative(
520: Collection<Assertion> alternative, Assertor assertor) {
521: PolicyInterceptorProviderRegistry pipr = bus
522: .getExtension(PolicyInterceptorProviderRegistry.class);
523: for (Assertion a : alternative) {
524: if (!(a.isOptional() || (null != pipr.get(a.getName())) || (null != assertor && assertor
525: .canAssert(a.getName())))) {
526: return false;
527: }
528: }
529: return true;
530: }
531:
532: /**
533: * Class used as key in the client request policy and server response policy maps.
534: */
535: class BindingOperation {
536: private EndpointInfo ei;
537: private BindingOperationInfo boi;
538:
539: BindingOperation(EndpointInfo e, BindingOperationInfo b) {
540: ei = e;
541: boi = b.isUnwrapped() ? b.getWrappedOperation() : b;
542: }
543:
544: EndpointInfo getEndpoint() {
545: return ei;
546: }
547:
548: BindingOperationInfo getBindingOperation() {
549: return boi;
550: }
551:
552: @Override
553: public int hashCode() {
554: return boi.hashCode();
555: }
556:
557: @Override
558: public boolean equals(Object obj) {
559: BindingOperation other = (BindingOperation) obj;
560: return boi.equals(other.boi) && ei.equals(other.ei);
561: }
562:
563: @Override
564: public String toString() {
565: return ei.getName().toString() + "."
566: + boi.getName().toString();
567: }
568:
569: }
570:
571: /**
572: * Class used as key in the server fault policy map.
573: */
574: class BindingFault {
575: private EndpointInfo ei;
576: private BindingFaultInfo bfi;
577:
578: BindingFault(EndpointInfo e, BindingFaultInfo b) {
579: ei = e;
580: bfi = b;
581: }
582:
583: EndpointInfo getEndpoint() {
584: return ei;
585: }
586:
587: BindingFaultInfo getBindingFault() {
588: return bfi;
589: }
590:
591: @Override
592: public int hashCode() {
593: return bfi.hashCode();
594: }
595:
596: @Override
597: public boolean equals(Object obj) {
598: BindingFault other = (BindingFault) obj;
599: return bfi.equals(other.bfi) && ei.equals(other.ei);
600: }
601:
602: @Override
603: public String toString() {
604: return ei.getName().toString() + "."
605: + bfi.getFaultInfo().toString();
606: }
607: }
608:
609: // for test
610:
611: EffectivePolicyImpl createOutPolicyInfo() {
612: return new EffectivePolicyImpl();
613: }
614:
615: EndpointPolicyImpl createEndpointPolicyInfo() {
616: return new EndpointPolicyImpl();
617: }
618: }
|