/** * Constructs the URL used to obtain meta data for a given document type identifier of a given * participant identifier. */ URL constructDocumentTypeURL( ParticipantId participantId, PeppolDocumentTypeId documentTypeIdentifier) { String scheme = ParticipantId.getScheme(); String value = participantId.stringValue(); String hostname = null; String urlString = null; try { hostname = "B-" + Util.calculateMD5(value.toLowerCase()) + "." + scheme + "." + smlHost; String encodedParticipant = URLEncoder.encode(scheme + "::" + value, "UTF-8"); String encodedDocumentId = URLEncoder.encode( PeppolDocumentTypeIdAcronym.getScheme() + "::" + documentTypeIdentifier.toString(), "UTF-8"); urlString = "http://" + hostname + "/" + encodedParticipant + "/services/" + encodedDocumentId; return new URL(urlString); } catch (MessageDigestException e) { throw new IllegalStateException( "Unable to calculate message digest for: " + participantId + ", doc.type:" + documentTypeIdentifier, e); } catch (UnsupportedEncodingException e) { throw new IllegalStateException("Unable to encode _" + scheme + "::" + value, e); } catch (MalformedURLException e) { throw new IllegalArgumentException("Unable to create URL from string:" + urlString, e); } }
/** * Retrieves an instance of the complete EndpointType for a given participant and the given * document type identifier. Given by the following XPath: * * <pre> * //ServiceMetadata/ServiceInformation/ProcessList/Process[0]/ServiceEndpointList/Endpoint[0] * </pre> * * @param participant the participant identifier * @param documentTypeIdentifier the document type identifier * @return the JAXB generated EndpointType object */ private EndpointType getEndpointType( ParticipantId participant, PeppolDocumentTypeId documentTypeIdentifier) { try { SignedServiceMetadataType serviceMetadata = getServiceMetaData(participant, documentTypeIdentifier); return selectOptimalEndpoint(serviceMetadata); } catch (Exception e) { String pid = (participant == null) ? "participant missing" : "for participant " + participant.toString(); String did = (documentTypeIdentifier == null) ? "document type missing" : "document type " + documentTypeIdentifier.toString(); throw new RuntimeException("Problem with SMP lookup " + pid + " and " + did, e); } }
/** Provides the end point data required for transmission of a message. */ @Override public PeppolEndpointData getEndpointTransmissionData( ParticipantId participantId, PeppolDocumentTypeId documentTypeIdentifier) { EndpointType endpointType = getEndpointType(participantId, documentTypeIdentifier); String transportProfile = endpointType.getTransportProfile(); String address = getEndPointUrl(endpointType); X509Certificate x509Certificate = getX509CertificateFromEndpointType(endpointType); try { return new PeppolEndpointData( new URL(address), BusDoxProtocol.instanceFrom(transportProfile), CommonName.valueOf(x509Certificate.getSubjectX500Principal())); } catch (Exception e) { throw new IllegalStateException( "Unable to provide end point data for " + participantId + " for " + documentTypeIdentifier.toString()); } }
/** * Retrieves a group of URLs representing the documents accepted by the given participant id * * @param participantId participant id to look up * @return list of URLs representing each document type accepted */ @Override public List<PeppolDocumentTypeId> getServiceGroups(ParticipantId participantId) throws SmpLookupException, ParticipantNotRegisteredException { // Creates the URL for the service meta data for the supplied participant URL serviceGroupURL = constructServiceGroupURL(participantId); if (!isParticipantRegistered(serviceGroupURL)) { throw new ParticipantNotRegisteredException(participantId); } NodeList nodes; List<PeppolDocumentTypeId> result = new ArrayList<PeppolDocumentTypeId>(); InputSource smpContents; /* When looking up ParticipantId("9908:976098897") we expected the SML not to resolve, but it actually did and we got a not found (HTTP 404) response from SMP instead (smp-basware.publisher.sml.peppolcentral.org). */ try { smpContents = smpContentRetriever.getUrlContent(serviceGroupURL); } catch (ConnectionException ex) { if (404 == ex.getCode()) { // signal that we got a NOT FOUND for that participant in the SMP throw new ParticipantNotRegisteredException(participantId); } else { throw ex; // re-throw exception } } // Parses the XML response from the SMP try { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); DocumentBuilder documentBuilder; Document document; documentBuilder = documentBuilderFactory.newDocumentBuilder(); document = documentBuilder.parse(smpContents); // Locates the namespace URI of the root element String nameSpaceURI = document.getDocumentElement().getNamespaceURI(); nodes = document.getElementsByTagNameNS(nameSpaceURI, "ServiceMetadataReference"); } catch (Exception e) { throw new SmpLookupException(participantId, serviceGroupURL, e); } // Loop the SMR elements, if any, and populate the result list if (nodes != null) { for (int i = 0; i < nodes.getLength(); i++) { String docTypeAsString = null; try { // Fetch href attribute Element element = (Element) nodes.item(i); String hrefAsString = element.getAttribute("href"); // Gets rid of all the funny %3A's... hrefAsString = URLDecoder.decode(hrefAsString, "UTF-8"); // Grabs the entire text string after "busdox-docid-qns::" docTypeAsString = hrefAsString.substring( hrefAsString.indexOf("busdox-docid-qns::") + "busdox-docid-qns::".length()); // Parses and creates the document type id PeppolDocumentTypeId peppolDocumentTypeId = PeppolDocumentTypeId.valueOf(docTypeAsString); result.add(peppolDocumentTypeId); } catch (Exception e) { /* ignore unparseable document types at runtime */ Log.warn( "Unable to create PeppolDocumentTypeId from " + docTypeAsString + ", got exception " + e.getMessage()); } } } return result; }