Java tutorial
/** * Copyright (C) 2015-2016 jochenberger & Philip Helger * * 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 com.helger.as2lib.partner.mongodb; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.bson.Document; import org.slf4j.Logger; import com.helger.as2lib.AbstractDynamicComponent; import com.helger.as2lib.exception.OpenAS2Exception; import com.helger.as2lib.message.IMessage; import com.helger.as2lib.message.IMessageMDN; import com.helger.as2lib.params.MessageParameters; import com.helger.as2lib.partner.CPartnershipIDs; import com.helger.as2lib.partner.IPartnershipFactory; import com.helger.as2lib.partner.Partnership; import com.helger.as2lib.partner.PartnershipNotFoundException; import com.helger.as2lib.util.IStringMap; import com.helger.commons.annotation.CodingStyleguideUnaware; import com.helger.commons.state.EChange; import com.mongodb.client.MongoCollection; import com.mongodb.client.model.IndexOptions; import com.mongodb.client.result.DeleteResult; /** * MongoDB based implementation of {@link IPartnershipFactory} * * @author jochenberger */ @CodingStyleguideUnaware public class MongoDBPartnershipFactory extends AbstractDynamicComponent implements IPartnershipFactory { private static final long serialVersionUID = -2282798646250446937L; private static final String NAME_KEY = "name"; private static final String RECEIVER_IDS = "receiver-ids"; private static final String SENDER_IDS = "sender-ids"; private static final String ATTRIBUTES = "attributes"; private final MongoCollection<Document> partnerships; private final Logger logger; public MongoDBPartnershipFactory(final MongoCollection<Document> partnerships, final Logger logger) { this.logger = logger; partnerships.createIndex(new Document(NAME_KEY, Integer.valueOf(1)), new IndexOptions().unique(true)); this.partnerships = partnerships; } @Override public EChange addPartnership(final Partnership aPartnership) throws OpenAS2Exception { partnerships.insertOne(toDocument(aPartnership)); return EChange.CHANGED; } @Override public EChange removePartnership(final Partnership aPartnership) throws OpenAS2Exception { final DeleteResult result = partnerships.deleteOne(new Document(NAME_KEY, aPartnership.getName())); if (result.getDeletedCount() >= 1l) { return EChange.CHANGED; } return EChange.UNCHANGED; } @Override public void updatePartnership(final IMessage aMsg, final boolean bOverwrite) throws OpenAS2Exception { // Fill in any available partnership information final Partnership aPartnership = getPartnership(aMsg.getPartnership()); logger.debug("Updating partnership {}", aPartnership); // Update partnership data of message with the stored ones aMsg.getPartnership().copyFrom(aPartnership); // Set attributes if (bOverwrite) { final String sSubject = aPartnership.getAttribute(CPartnershipIDs.PA_SUBJECT); if (sSubject != null) { aMsg.setSubject(new MessageParameters(aMsg).format(sSubject)); } } } @Override public void updatePartnership(final IMessageMDN aMdn, final boolean bOverwrite) throws OpenAS2Exception { final Partnership aPartnership = getPartnership(aMdn.getPartnership()); aMdn.getPartnership().copyFrom(aPartnership); } @Override public Partnership getPartnership(final Partnership aPartnership) throws OpenAS2Exception { Partnership aRealPartnership = getPartnershipByName(aPartnership.getName()); if (aRealPartnership == null) { // Found no partnership by name aRealPartnership = getPartnershipByID(aPartnership.getAllSenderIDs(), aPartnership.getAllReceiverIDs()); } if (aRealPartnership == null) { throw new PartnershipNotFoundException(aPartnership); } return aRealPartnership; } private Partnership getPartnershipByID(final IStringMap allSenderIDs, final IStringMap allReceiverIDs) { Document filter = new Document(); for (final Entry<String, String> entry : allSenderIDs) { filter.append(SENDER_IDS + "." + entry.getKey(), entry.getValue()); } for (final Entry<String, String> entry : allReceiverIDs) { filter.append(RECEIVER_IDS + "." + entry.getKey(), entry.getValue()); } Partnership result = partnerships.find(filter).map(MongoDBPartnershipFactory::toPartnership).first(); if (result != null) { return result; } // try the other way around, maybe we're receiving a response // TODO is this really a good idea? filter = new Document(); for (final Entry<String, String> entry : allSenderIDs) { filter.append(RECEIVER_IDS + "." + entry.getKey(), entry.getValue()); } for (final Entry<String, String> entry : allReceiverIDs) { filter.append(SENDER_IDS + "." + entry.getKey(), entry.getValue()); } final Partnership inverseResult = partnerships.find(filter).map(MongoDBPartnershipFactory::toPartnership) .first(); if (inverseResult != null) { result = new Partnership(inverseResult.getName() + "-inverse"); result.setReceiverX509Alias(inverseResult.getSenderX509Alias()); result.setReceiverAS2ID(inverseResult.getSenderAS2ID()); result.setSenderX509Alias(inverseResult.getReceiverX509Alias()); result.setSenderAS2ID(inverseResult.getReceiverAS2ID()); return result; } return null; } @Override public Partnership getPartnershipByName(final String sName) { return partnerships.find(new Document(NAME_KEY, sName)).map(MongoDBPartnershipFactory::toPartnership) .first(); } @Override public Set<String> getAllPartnershipNames() { return partnerships.distinct(NAME_KEY, String.class).into(new HashSet<>()); } @Override public List<Partnership> getAllPartnerships() { return partnerships.find().map(MongoDBPartnershipFactory::toPartnership).into(new ArrayList<>()); } private static Document toDocument(final IStringMap stringMap) { final Document document = new Document(); for (final Entry<String, String> entry : stringMap) { document.put(entry.getKey(), entry.getValue()); } return document; } private static Document toDocument(final Partnership partnership) { final Document document = new Document(); document.put(NAME_KEY, partnership.getName()); document.put(RECEIVER_IDS, toDocument(partnership.getAllReceiverIDs())); document.put(SENDER_IDS, toDocument(partnership.getAllSenderIDs())); document.put(ATTRIBUTES, toDocument(partnership.getAllAttributes())); return document; } private static Partnership toPartnership(final Document document) { final Partnership partnership = new Partnership(document.getString(NAME_KEY)); final Document senderIDs = (Document) document.get(SENDER_IDS); final Map<String, String> senders = new HashMap<>(senderIDs.size()); for (final Entry<String, Object> e : senderIDs.entrySet()) { senders.put(e.getKey(), e.getValue().toString()); } partnership.addSenderIDs(senders); final Document receiverIDs = (Document) document.get(RECEIVER_IDS); final Map<String, String> receivers = new HashMap<>(receiverIDs.size()); for (final Entry<String, Object> e : receiverIDs.entrySet()) { receivers.put(e.getKey(), e.getValue().toString()); } partnership.addReceiverIDs(receivers); final Document attributes = (Document) document.get(ATTRIBUTES); if (attributes != null) { final Map<String, String> att = new HashMap<>(receiverIDs.size()); for (final Entry<String, Object> e : attributes.entrySet()) { att.put(e.getKey(), e.getValue().toString()); } partnership.addAllAttributes(att); } return partnership; } }