001: /*
002: * <copyright>
003: *
004: * Copyright 2002-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.pizza.plugin.util;
028:
029: import java.io.Serializable;
030: import java.util.Collection;
031: import java.util.Iterator;
032:
033: import org.cougaar.pizza.Constants;
034: import org.cougaar.planning.ldm.plan.Role;
035: import org.cougaar.servicediscovery.description.ServiceClassification;
036: import org.cougaar.servicediscovery.description.ServiceInfo;
037: import org.cougaar.servicediscovery.description.ServiceInfoScorer;
038:
039: import org.cougaar.util.log.Logger;
040: import org.cougaar.util.log.Logging;
041:
042: /**
043: * ServiceDiscovery Service scoring function using <code>Role</code> name and an
044: * exclusion list.
045: * <br><pre>
046: * Uses 2 criteria -
047: * service role must match scorer role (in Commercial Service Scheme)
048: * service provider name must not match one of the names on the blacklist.
049: *</pre><p>
050: * All passing descriptions get a score of 1, all failing descriptions get
051: * a score of -1.
052: * <p>
053: * <code>SDClientPlugin</code> creates the <code>RoleWithBlacklistScorer</code> and attaches it to the <code>MMQueryRequest</code>.
054: * <code>MatchmakerPlugin</code> uses the <code>RoleWithBlacklistScorer</code> to evaluate service descriptions
055: * returned from the yellow pages. All passing service descriptions are added
056: * to the <code>MMQueryRequest</code> results field.
057: *<p>
058: * This Scorer is a simple variation on the RoleScorer in the ServiceDiscovery module, as an example
059: * of how to modify this.
060: *
061: * @see org.cougaar.servicediscovery.util.RoleScorer
062: */
063: public class RoleWithBlacklistScorer implements ServiceInfoScorer,
064: Serializable {
065: // Note this is how a non-component can get a Logger
066: private static Logger logger = Logging
067: .getLogger(RoleWithBlacklistScorer.class);
068: private Role myRole; // The role we want
069: private Collection myBlacklist; // providers to exclude -- for example, those we've already tried
070:
071: public RoleWithBlacklistScorer(Role role, Collection blacklist) {
072: myRole = role;
073: myBlacklist = blacklist;
074: }
075:
076: /**
077: * What Role is being requested?
078: * @return the Role required for this request
079: **/
080: public Role getRole() {
081: return myRole;
082: }
083:
084: /**
085: * Which providers are not acceptable?
086: * @return the Collection of excluded provider names (Strings)
087: **/
088: public Collection getBlacklist() {
089: return myBlacklist;
090: }
091:
092: /**
093: * Will be called by MatchmakerPlugin for each ServiceInfo. Returned score will
094: * be added to the ScoredServiceDescription associated with the Service.
095: *
096: * @param serviceInfo The ServiceInfo returned by the YP for which we want a score
097: * @return int representing score. Client responsible for
098: * understanding the precise value. Current usage assumes lowest value >= 0
099: * is the best. Values less than 0 indicate the provider is not suitable.
100: *
101: */
102: public int scoreServiceInfo(ServiceInfo serviceInfo) {
103: // If the blacklist scoring says the provider is no good, its no good
104: if (getBlacklistScore(serviceInfo) < 0) {
105: return -1;
106: }
107:
108: // Otherwise, we just use the role score
109: int roleScore = getRoleScore(serviceInfo);
110:
111: return roleScore;
112: }
113:
114: /**
115: * Score the role portion -- lowest non-negative score is best.
116: * Note that it assumes that the Role is in the Commercial Service Scheme.
117: */
118: private int getRoleScore(ServiceInfo serviceInfo) {
119: String serviceRole = null;
120:
121: // Find the correct service classification code
122: for (Iterator iterator = serviceInfo
123: .getServiceClassifications().iterator(); iterator
124: .hasNext();) {
125: ServiceClassification classification = (ServiceClassification) iterator
126: .next();
127: // Here we assume / require where the Role will be classified
128: if (classification.getClassificationSchemeName().equals(
129: Constants.UDDIConstants.COMMERCIAL_SERVICE_SCHEME)) {
130:
131: serviceRole = classification.getClassificationCode();
132: break;
133: }
134: }
135:
136: if (serviceRole == null) {
137: if (logger.isInfoEnabled()) {
138: logger
139: .info("Ignoring service (score is -1) with a bad service role for provider: "
140: + serviceInfo.getProviderName());
141: }
142: return -1;
143: } else if (!serviceRole.equals(myRole.toString())) {
144: // If this is not the role we're looking for, score it down
145: if (logger.isInfoEnabled()) {
146: logger
147: .info("Ignoring service (score is -1) with (wrong) Role of: "
148: + serviceRole
149: + ", was looking for role "
150: + myRole
151: + " for provider: "
152: + serviceInfo.getProviderName());
153: }
154: return -1;
155: } else {
156: // This is the role we're looking for!
157: if (logger.isInfoEnabled()) {
158: logger
159: .info("Found good service (score is 0) with matching Role of: "
160: + serviceRole
161: + " on provider: "
162: + serviceInfo.getProviderName());
163: }
164: return 0;
165: }
166: }
167:
168: /** Score the service provider relative to the blacklist - if it's blacklisted, it gets -1 */
169: private int getBlacklistScore(ServiceInfo serviceInfo) {
170: // Look for the serviceInfo's ProviderName on the blacklist
171: for (Iterator iterator = myBlacklist.iterator(); iterator
172: .hasNext();) {
173: String blacklistedProvider = (String) iterator.next();
174:
175: if (serviceInfo.getProviderName().equals(
176: blacklistedProvider)) {
177: if (logger.isInfoEnabled()) {
178: logger
179: .info("Ignoring service (score is -1) from blacklisted provider - "
180: + serviceInfo.getProviderName()
181: + ". Provider on the blacklist - "
182: + myBlacklist);
183: }
184: // -1 means don't use this provider
185: return -1;
186: }
187: } // loop over blacklist entries
188:
189: // Didn't find it on the Blacklist -- its good
190: return 0;
191: }
192:
193: public String toString() {
194: return "<RoleWithBlacklistScorer Role: " + myRole
195: + ", Blacklist: " + myBlacklist + ">";
196: }
197:
198: }
|