| <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>ValidateReplication.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">jUDDI Core - OpenJPA</a> > <a href="index.source.html" class="el_package">org.apache.juddi.validation</a> > <span class="el_source">ValidateReplication.java</span></div><h1>ValidateReplication.java</h1><pre class="source lang-java linenums">/* |
| * Copyright 2001-2008 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| package org.apache.juddi.validation; |
| |
| import java.io.UnsupportedEncodingException; |
| import java.math.BigInteger; |
| import java.security.cert.CertificateException; |
| import java.util.List; |
| import java.util.Properties; |
| import java.util.concurrent.atomic.AtomicReference; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.persistence.EntityManager; |
| import javax.xml.ws.WebServiceContext; |
| import org.apache.commons.configuration.Configuration; |
| import org.apache.commons.configuration.ConfigurationException; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import static org.apache.juddi.api.impl.AuthenticatedService.UTF8; |
| import org.apache.juddi.config.AppConfig; |
| import org.apache.juddi.config.Property; |
| import org.apache.juddi.model.Node; |
| import org.apache.juddi.model.UddiEntityPublisher; |
| import org.apache.juddi.v3.client.cryptor.CryptorFactory; |
| import org.apache.juddi.v3.client.cryptor.DigSigUtil; |
| import org.apache.juddi.v3.error.ErrorMessage; |
| import org.apache.juddi.v3.error.FatalErrorException; |
| import org.apache.juddi.v3.error.InvalidValueException; |
| import org.apache.juddi.v3.error.TransferNotAllowedException; |
| import org.apache.juddi.v3.error.ValueNotAllowedException; |
| import org.uddi.custody_v3.TransferEntities; |
| import org.uddi.repl_v3.CommunicationGraph.Edge; |
| import org.uddi.repl_v3.HighWaterMarkVectorType; |
| import org.uddi.repl_v3.NotifyChangeRecordsAvailable; |
| import org.uddi.repl_v3.Operator; |
| import org.uddi.repl_v3.ReplicationConfiguration; |
| import org.uddi.repl_v3.TransferCustody; |
| import org.uddi.v3_service.DispositionReportFaultMessage; |
| |
| /** |
| * @author <a href="mailto:alexoree@apache.org">Alex O'Ree</a> |
| * Processing an inbound replication message may fail due to a server internal |
| * error. The common behavior for all error cases is to return an E_fatalError |
| * error code. Error reporting SHALL be that specified by Section 4.8 – Success |
| * and Error Reporting of this specification. |
| */ |
| public class ValidateReplication extends ValidateUDDIApi { |
| |
| <span class="fc" id="L63"> private final static Log log = LogFactory.getLog(ValidateReplication.class);</span> |
| public ValidateReplication(UddiEntityPublisher publisher) { |
| <span class="fc" id="L65"> super(publisher);</span> |
| <span class="fc" id="L66"> }</span> |
| |
| public ValidateReplication(UddiEntityPublisher publisher, String nodeid) { |
| <span class="fc" id="L69"> super(publisher, nodeid);</span> |
| <span class="fc" id="L70"> }</span> |
| |
| public void validateNotifyChangeRecordsAvailable(NotifyChangeRecordsAvailable body, WebServiceContext ctx) throws DispositionReportFaultMessage { |
| //TODO |
| <span class="nc" id="L74"> }</span> |
| |
| public void validateGetChangeRecords(String requestingNode, HighWaterMarkVectorType changesAlreadySeen, BigInteger responseLimitCount, HighWaterMarkVectorType responseLimitVector, ReplicationConfiguration FetchEdges, WebServiceContext ctx) throws DispositionReportFaultMessage { |
| //TODO |
| |
| <span class="nc bnc" id="L79" title="All 4 branches missed."> if (requestingNode == null || requestingNode.trim().equalsIgnoreCase("")) {</span> |
| //requestingNode: The requestingNode element provides the identity of the calling node. |
| //This is the unique key for the calling node and SHOULD be specified within the Replication Configuration Structure. |
| <span class="nc" id="L82"> throw new FatalErrorException(new ErrorMessage("errors.replication.nodeNotSpecified"));</span> |
| } |
| //if (!ContainsNode(requestingNode, FetchEdges)) { |
| // throw new FatalErrorException(new ErrorMessage("errors.replication.unknownNode")); |
| //} |
| |
| <span class="nc bnc" id="L88" title="All 2 branches missed."> if (changesAlreadySeen != null) {</span> |
| // changesAlreadySeen: The changesAlreadySeen element, if present, indicates changes from each |
| //node that the requestor has successfully processed, and thus which should not be resent, if possible. |
| |
| //no validation needed? |
| } |
| |
| <span class="nc bnc" id="L95" title="All 4 branches missed."> if (responseLimitCount != null && responseLimitVector != null) {</span> |
| <span class="nc" id="L96"> throw new FatalErrorException(new ErrorMessage("errors.replication.bothLimitsSpecified"));</span> |
| } |
| <span class="nc bnc" id="L98" title="All 2 branches missed."> if (responseLimitCount != null) {</span> |
| //can't be 0 since 0 is banned as being a change record id |
| <span class="nc bnc" id="L100" title="All 2 branches missed."> if (responseLimitCount.longValue() <= 0) {</span> |
| <span class="nc" id="L101"> throw new FatalErrorException(new ErrorMessage("errors.replication.negativeLimit", responseLimitCount.toString()));</span> |
| } |
| } |
| <span class="nc bnc" id="L104" title="All 2 branches missed."> if (responseLimitVector != null) {</span> |
| <span class="nc bnc" id="L105" title="All 2 branches missed."> for (int i = 0; i < responseLimitVector.getHighWaterMark().size(); i++) {</span> |
| <span class="nc bnc" id="L106" title="All 2 branches missed."> if (responseLimitVector.getHighWaterMark().get(i).getOriginatingUSN() == null</span> |
| <span class="nc bnc" id="L107" title="All 2 branches missed."> || responseLimitVector.getHighWaterMark().get(i).getOriginatingUSN() <= 0) {</span> |
| <span class="nc" id="L108"> throw new FatalErrorException(new ErrorMessage("errors.replication.limitVectorNull"));</span> |
| } |
| <span class="nc bnc" id="L110" title="All 2 branches missed."> if (responseLimitVector.getHighWaterMark().get(i).getNodeID() == null</span> |
| <span class="nc bnc" id="L111" title="All 2 branches missed."> || responseLimitVector.getHighWaterMark().get(i).getNodeID().trim().equalsIgnoreCase("")) {</span> |
| <span class="nc" id="L112"> throw new FatalErrorException(new ErrorMessage("errors.replication.limitVectorNoNode"));</span> |
| } |
| } |
| } |
| |
| /** |
| * responseLimitCount or responseLimitVector: A caller MAY place |
| * an upper bound on the number of change records he wishes to |
| * receive in response to this message by either providing a |
| * integer responseLimitCount, or, using responseLimitVector, |
| * indicating for each node in the graph the first change |
| * originating there that he does not wish to be returned. |
| * |
| */ |
| <span class="nc" id="L126"> }</span> |
| |
| private static boolean ContainsNode(String requestingNode, ReplicationConfiguration FetchEdges) { |
| <span class="nc bnc" id="L129" title="All 2 branches missed."> if (FetchEdges == null) {</span> |
| <span class="nc" id="L130"> return false;</span> |
| } |
| <span class="nc bnc" id="L132" title="All 2 branches missed."> if (FetchEdges.getCommunicationGraph() == null) {</span> |
| <span class="nc" id="L133"> return false;</span> |
| } |
| <span class="nc bnc" id="L135" title="All 2 branches missed."> for (int i = 0; i < FetchEdges.getCommunicationGraph().getNode().size(); i++) {</span> |
| <span class="nc bnc" id="L136" title="All 2 branches missed."> if (FetchEdges.getCommunicationGraph().getNode().get(i).equalsIgnoreCase(requestingNode)) {</span> |
| <span class="nc" id="L137"> return true;</span> |
| } |
| } |
| <span class="nc" id="L140"> return false;</span> |
| } |
| |
| public void validateSetReplicationNodes(ReplicationConfiguration replicationConfiguration, EntityManager em, String thisnode, Configuration config) throws DispositionReportFaultMessage, ConfigurationException { |
| <span class="pc bpc" id="L144" title="1 of 2 branches missed."> if (replicationConfiguration == null) {</span> |
| <span class="nc" id="L145"> throw new InvalidValueException(new ErrorMessage("errors.replication.configNull"));</span> |
| |
| } |
| <span class="pc bpc" id="L148" title="1 of 2 branches missed."> if (replicationConfiguration.getCommunicationGraph() == null) {</span> |
| <span class="nc" id="L149"> throw new InvalidValueException(new ErrorMessage("errors.replication.configNull"));</span> |
| } |
| <span class="pc bpc" id="L151" title="1 of 2 branches missed."> if (replicationConfiguration.getRegistryContact() == null) {</span> |
| <span class="nc" id="L152"> throw new InvalidValueException(new ErrorMessage("errors.replication.contactNull"));</span> |
| } |
| <span class="pc bpc" id="L154" title="1 of 2 branches missed."> if (replicationConfiguration.getRegistryContact().getContact() == null) {</span> |
| <span class="nc" id="L155"> throw new InvalidValueException(new ErrorMessage("errors.replication.contactNull"));</span> |
| } |
| <span class="pc bpc" id="L157" title="1 of 2 branches missed."> if (replicationConfiguration.getRegistryContact().getContact().getPersonName().get(0) == null) {</span> |
| <span class="nc" id="L158"> throw new InvalidValueException(new ErrorMessage("errors.replication.contactNull"));</span> |
| } |
| |
| <span class="pc bpc" id="L161" title="2 of 4 branches missed."> if (replicationConfiguration.getOperator() == null || replicationConfiguration.getOperator().isEmpty()) {</span> |
| <span class="nc" id="L162"> throw new InvalidValueException(new ErrorMessage("errors.replication.contactNull", "Operator is null or empty"));</span> |
| } |
| <span class="fc bfc" id="L164" title="All 2 branches covered."> for (int i = 0; i < replicationConfiguration.getOperator().size(); i++) {</span> |
| <span class="pc bpc" id="L165" title="1 of 2 branches missed."> if (replicationConfiguration.getOperator().get(i).getSoapReplicationURL() == null</span> |
| <span class="pc bpc" id="L166" title="1 of 2 branches missed."> || "".equals(replicationConfiguration.getOperator().get(i).getSoapReplicationURL())) {</span> |
| <span class="nc" id="L167"> throw new InvalidValueException(new ErrorMessage("errors.replication.contactNull", "Replication URL is null or empty"));</span> |
| } |
| <span class="pc bpc" id="L169" title="1 of 2 branches missed."> if (!replicationConfiguration.getOperator().get(i).getSoapReplicationURL().toLowerCase().startsWith("http")) {</span> |
| <span class="nc" id="L170"> throw new InvalidValueException(new ErrorMessage("errors.replication.contactNull", "Replication URL is invalid, only HTTP is supported"));</span> |
| } |
| <span class="pc bpc" id="L172" title="1 of 2 branches missed."> if (replicationConfiguration.getOperator().get(i).getOperatorNodeID() == null</span> |
| <span class="pc bpc" id="L173" title="1 of 2 branches missed."> || replicationConfiguration.getOperator().get(i).getOperatorNodeID().equalsIgnoreCase("")) {</span> |
| <span class="nc" id="L174"> throw new InvalidValueException(new ErrorMessage("errors.replication.contactNull", "Node ID is not defined"));</span> |
| } |
| } |
| <span class="pc bpc" id="L177" title="1 of 2 branches missed."> if (replicationConfiguration.getCommunicationGraph() != null) {</span> |
| <span class="fc bfc" id="L178" title="All 2 branches covered."> for (String s : replicationConfiguration.getCommunicationGraph().getNode()) {</span> |
| <span class="pc bpc" id="L179" title="1 of 2 branches missed."> if (!Contains(replicationConfiguration.getOperator(), s)) {</span> |
| <span class="nc" id="L180"> throw new InvalidValueException(new ErrorMessage("errors.replication.configNodeNotFound"));</span> |
| } |
| <span class="fc" id="L182"> }</span> |
| <span class="fc bfc" id="L183" title="All 2 branches covered."> for (Edge s : replicationConfiguration.getCommunicationGraph().getEdge()) {</span> |
| //TODO revisit this for correctness |
| //Node find = null; |
| //if (!thisnode.equalsIgnoreCase(s.getMessageReceiver())) { |
| <span class="pc bpc" id="L187" title="1 of 2 branches missed."> if (!Contains(replicationConfiguration.getOperator(), s.getMessageReceiver())) {</span> |
| <span class="nc" id="L188"> throw new InvalidValueException(new ErrorMessage("errors.replication.configNodeNotFound"));</span> |
| //} |
| } |
| //find = null; |
| //if (!thisnode.equalsIgnoreCase(s.getMessageSender())) { |
| <span class="pc bpc" id="L193" title="1 of 2 branches missed."> if (!Contains(replicationConfiguration.getOperator(), s.getMessageSender())) {</span> |
| <span class="nc" id="L194"> throw new InvalidValueException(new ErrorMessage("errors.replication.configNodeNotFound"));</span> |
| //} |
| } |
| <span class="pc bpc" id="L197" title="1 of 2 branches missed."> if (s.getMessageReceiver().equalsIgnoreCase(s.getMessageSender())){</span> |
| <span class="nc" id="L198"> throw new InvalidValueException(new ErrorMessage("errors.replication.configNodeLoop"));</span> |
| } |
| <span class="fc bfc" id="L200" title="All 2 branches covered."> for (String id : s.getMessageReceiverAlternate()) {</span> |
| <span class="pc bpc" id="L201" title="1 of 2 branches missed."> if (!Contains(replicationConfiguration.getOperator(), id)) {</span> |
| <span class="nc" id="L202"> throw new InvalidValueException(new ErrorMessage("errors.replication.configNodeNotFound"));</span> |
| } |
| <span class="fc" id="L204"> }</span> |
| |
| <span class="fc" id="L206"> }</span> |
| } |
| <span class="fc" id="L208"> boolean shouldcheck = config.getBoolean(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_ENABLE, false);</span> |
| <span class="fc" id="L209"> initDigSig(config);</span> |
| <span class="pc bpc" id="L210" title="5 of 6 branches missed."> if (shouldcheck && !replicationConfiguration.getSignature().isEmpty() && ds != null) {</span> |
| <span class="nc" id="L211"> AtomicReference<String> outmsg = new AtomicReference<String>();</span> |
| <span class="nc" id="L212"> boolean ok = ds.verifySignedUddiEntity(replicationConfiguration, outmsg);</span> |
| <span class="nc bnc" id="L213" title="All 2 branches missed."> if (!ok) {</span> |
| <span class="nc" id="L214"> throw new FatalErrorException(new ErrorMessage("errors.digitalsignature.validationfailure" + " " + outmsg.get()));</span> |
| } |
| |
| } |
| <span class="fc" id="L218"> }</span> |
| |
| <span class="fc" id="L220"> private org.apache.juddi.v3.client.cryptor.DigSigUtil ds = null;</span> |
| |
| private synchronized void initDigSig(Configuration config) { |
| <span class="pc bpc" id="L223" title="1 of 2 branches missed."> if (ds == null) {</span> |
| |
| <span class="fc" id="L225"> Properties p = new Properties();</span> |
| /** |
| * <trustStorePath>truststore.jks</trustStorePath> |
| * <trustStoreType>JKS</trustStoreType> |
| * <trustStorePassword |
| * isPasswordEncrypted="false" |
| * cryptoProvider="org.apache.juddi.v3.client.crypto.AES128Cryptor">password</trustStorePassword> |
| * |
| * <checkTimestamps>true</checkTimestamps> |
| * <checkTrust>true</checkTrust> |
| * <checkRevocationCRL>true</checkRevocationCRL> |
| */ |
| <span class="fc" id="L237"> p.put(DigSigUtil.TRUSTSTORE_FILE, config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "trustStorePath", ""));</span> |
| <span class="fc" id="L238"> p.put(DigSigUtil.TRUSTSTORE_FILETYPE, config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "trustStoreType", ""));</span> |
| |
| <span class="fc" id="L240"> String enc = config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "trustStorePassword", "");</span> |
| <span class="pc bpc" id="L241" title="1 of 2 branches missed."> if (config.getBoolean(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "trustStorePassword[@isPasswordEncrypted]", false)) {</span> |
| <span class="nc" id="L242"> log.debug("trust password is encrypted, decrypting...");</span> |
| |
| <span class="nc" id="L244"> String prov = config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "trustStorePassword[@cryptoProvider]", "");</span> |
| try { |
| <span class="nc" id="L246"> p.setProperty(DigSigUtil.TRUSTSTORE_FILE_PASSWORD, CryptorFactory.getCryptor(prov).decrypt(enc));</span> |
| <span class="nc" id="L247"> } catch (Exception ex) {</span> |
| <span class="nc" id="L248"> log.warn("unable to decrypt trust store password " + ex.getMessage());</span> |
| <span class="nc" id="L249"> log.debug("unable to decrypt trust store password " + ex.getMessage(), ex);</span> |
| <span class="nc" id="L250"> }</span> |
| |
| <span class="pc bpc" id="L252" title="1 of 2 branches missed."> } else if (!"".equals(enc)){</span> |
| <span class="nc" id="L253"> log.warn("Hey, you should consider encrypting your trust store password!");</span> |
| <span class="nc" id="L254"> p.setProperty(DigSigUtil.TRUSTSTORE_FILE_PASSWORD, enc);</span> |
| } |
| |
| <span class="fc" id="L257"> p.put(DigSigUtil.CHECK_REVOCATION_STATUS_CRL, config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "checkRevocationCRL", "true"));</span> |
| <span class="fc" id="L258"> p.put(DigSigUtil.CHECK_TRUST_CHAIN, config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "checkTrust", "true"));</span> |
| <span class="fc" id="L259"> p.put(DigSigUtil.CHECK_TIMESTAMPS, config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "checkTimestamps", "true"));</span> |
| |
| try { |
| <span class="fc" id="L262"> ds = new DigSigUtil(p);</span> |
| <span class="nc" id="L263"> } catch (CertificateException ex) {</span> |
| <span class="nc" id="L264"> log.error("", ex);</span> |
| <span class="fc" id="L265"> }</span> |
| //System.out.println("loaded from " + AppConfig.getConfigFileURL()); |
| //p.list(System.out); |
| } |
| <span class="fc" id="L269"> }</span> |
| |
| |
| |
| private boolean Contains(List<Operator> operator, String s) { |
| <span class="pc bpc" id="L274" title="1 of 2 branches missed."> if (operator == null) {</span> |
| <span class="nc" id="L275"> return false;</span> |
| } |
| <span class="pc bpc" id="L277" title="1 of 2 branches missed."> for (Operator o : operator) {</span> |
| <span class="fc bfc" id="L278" title="All 2 branches covered."> if (o.getOperatorNodeID().equalsIgnoreCase(s)) {</span> |
| <span class="fc" id="L279"> return true;</span> |
| } |
| <span class="fc" id="L281"> }</span> |
| <span class="nc" id="L282"> return false;</span> |
| } |
| |
| public void validateTransfer(EntityManager em, TransferCustody body) throws DispositionReportFaultMessage { |
| |
| <span class="nc bnc" id="L287" title="All 2 branches missed."> if (body == null) {</span> |
| <span class="nc" id="L288"> throw new TransferNotAllowedException(new ErrorMessage("errors.NullInput"));</span> |
| } |
| <span class="nc bnc" id="L290" title="All 2 branches missed."> if (body.getTransferToken() == null) {</span> |
| <span class="nc" id="L291"> throw new TransferNotAllowedException(new ErrorMessage("errors.NullInput"));</span> |
| } |
| <span class="nc bnc" id="L293" title="All 2 branches missed."> if (body.getKeyBag() == null) {</span> |
| <span class="nc" id="L294"> throw new TransferNotAllowedException(new ErrorMessage("errors.NullInput"));</span> |
| } |
| <span class="nc bnc" id="L296" title="All 2 branches missed."> if (body.getTransferOperationalInfo() == null) {</span> |
| <span class="nc" id="L297"> throw new TransferNotAllowedException(new ErrorMessage("errors.NullInput"));</span> |
| } |
| |
| <span class="nc bnc" id="L300" title="All 2 branches missed."> if (body.getTransferOperationalInfo().getNodeID() == null) {</span> |
| <span class="nc" id="L301"> throw new TransferNotAllowedException(new ErrorMessage("errors.NullInput"));</span> |
| } |
| <span class="nc bnc" id="L303" title="All 2 branches missed."> if (body.getTransferOperationalInfo().getAuthorizedName() == null) {</span> |
| <span class="nc" id="L304"> throw new TransferNotAllowedException(new ErrorMessage("errors.NullInput"));</span> |
| } |
| |
| //confirm i own the records in question |
| //confirm i issued the transfer token |
| <span class="nc" id="L309"> TransferEntities x = new TransferEntities();</span> |
| <span class="nc" id="L310"> x.setKeyBag(body.getKeyBag());</span> |
| <span class="nc" id="L311"> x.setTransferToken(body.getTransferToken());</span> |
| String transferTokenId; |
| try { |
| <span class="nc" id="L314"> transferTokenId = new String(body.getTransferToken().getOpaqueToken(), UTF8);</span> |
| <span class="nc" id="L315"> } catch (UnsupportedEncodingException ex) {</span> |
| <span class="nc" id="L316"> throw new InvalidValueException(new ErrorMessage("errors.stringEncoding"));</span> |
| <span class="nc" id="L317"> }</span> |
| <span class="nc" id="L318"> new ValidateCustodyTransfer(null).validateTransferLocalEntities(em, transferTokenId, body.getKeyBag().getKey());</span> |
| |
| <span class="nc" id="L320"> }</span> |
| |
| } |
| </pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.7.9.201702052155</span></div></body></html> |