package org.ourgrid.peer.business.requester; import java.util.ArrayList; import java.util.List; import org.ourgrid.common.interfaces.to.LocalWorkerState; import org.ourgrid.common.interfaces.to.RequestSpecification; import org.ourgrid.common.internal.IResponseTO; import org.ourgrid.common.internal.RequesterIF; import org.ourgrid.common.internal.response.LoggerResponseTO; import org.ourgrid.common.internal.response.RegisterInterestResponseTO; import org.ourgrid.common.statistics.control.JobControl; import org.ourgrid.common.statistics.control.UserControl; import org.ourgrid.common.statistics.control.WorkerControl; import org.ourgrid.common.util.StringUtil; import org.ourgrid.peer.business.controller.CommunityObtainerController; import org.ourgrid.peer.business.controller.allocation.DefaultAllocator; import org.ourgrid.peer.business.controller.messages.RequestMessages; import org.ourgrid.peer.business.dao.PeerDAOFactory; import org.ourgrid.peer.business.util.RequestUtils; import org.ourgrid.peer.request.RequestWorkersRequestTO; import org.ourgrid.peer.response.LocalPreemptedWorkerResponseTO; import org.ourgrid.peer.response.RemotePreemptedWorkerResponseTO; import org.ourgrid.peer.to.AllocableWorker; import org.ourgrid.peer.to.LocalConsumer; import org.ourgrid.peer.to.LocalWorker; import org.ourgrid.peer.to.PeerUser; import org.ourgrid.peer.to.PeerUserReference; import org.ourgrid.peer.to.Request; import sun.security.provider.certpath.X509CertPath; public class RequestWorkersRequester implements RequesterIF<RequestWorkersRequestTO> { public List<IResponseTO> execute(RequestWorkersRequestTO requestTO) { List<IResponseTO> responses = new ArrayList<IResponseTO>(); String userPubKey = requestTO.getBrokerPublicKey(); RequestSpecification requestSpec = requestTO.getRequestSpec(); if(UserControl.getInstance().userExists(responses, userPubKey)) { if (!validateRequest(responses, requestSpec, userPubKey)) { return responses; } PeerUserReference loggedUser = PeerDAOFactory.getInstance().getUsersDAO().getLoggedUser( userPubKey); if (loggedUser == null) { LoggerResponseTO loggerResponse = new LoggerResponseTO( RequestMessages.getUserDownMessage(requestSpec.getRequestId(), userPubKey), LoggerResponseTO.WARN); responses.add(loggerResponse); return responses; } String localWorkerProviderClientAddress = loggedUser.getWorkerProviderClientAddress(); if (localWorkerProviderClientAddress == null) { LoggerResponseTO loggerResponse = new LoggerResponseTO( RequestMessages.getUserDownMessage(requestSpec.getRequestId(), userPubKey), LoggerResponseTO.WARN); responses.add(loggerResponse); return responses; } //Do not allow Broker to repeat the request if(requestIsRunning(requestSpec)) { LoggerResponseTO loggerResponse = new LoggerResponseTO( RequestMessages.getRequestIDAlreadyExistsMessage(requestSpec.getRequestId(), localWorkerProviderClientAddress), LoggerResponseTO.WARN); responses.add(loggerResponse); return responses; } LoggerResponseTO loggerResponse = new LoggerResponseTO( RequestMessages.getNewRequestMessage(requestSpec, localWorkerProviderClientAddress), LoggerResponseTO.INFO); responses.add(loggerResponse); PeerUser user = UserControl.getInstance().getUserByPublicKey(responses, userPubKey); LocalConsumer localConsumer = PeerDAOFactory.getInstance().getConsumerDAO().createLocalConsumer(user); Request request = PeerDAOFactory.getInstance().getRequestDAO().createRequest( localWorkerProviderClientAddress, userPubKey, requestSpec, localConsumer); doRequest(responses, requestTO.getMyCertPath(), requestSpec, requestTO.getMyPublicKey(), userPubKey, request, false); //Request repetition } else if (userPubKey.equals(requestTO.getMyPublicKey())) { Request request = PeerDAOFactory.getInstance().getRequestDAO().getRequest(requestSpec.getRequestId()); if(request != null) { doRequest(responses, requestTO.getMyCertPath(), requestSpec, requestTO.getMyPublicKey(), request.getConsumer().getPublicKey(), request, true); } } else { LoggerResponseTO loggerResponse = new LoggerResponseTO( RequestMessages.getUnknownUserMessage(requestSpec, userPubKey), LoggerResponseTO.WARN); responses.add(loggerResponse); } return responses; } public void doRequest(List<IResponseTO> responses, X509CertPath myCertPath, RequestSpecification requestSpec, String myPublicKey, String userPublicKey, Request request, boolean isRepetition) { DefaultAllocator allocator = DefaultAllocator.getInstance(); List<AllocableWorker> allAllocableWorkers = PeerDAOFactory.getInstance().getAllocationDAO().getAllAllocableWorkers(); List<AllocableWorker> myAllocableWorkersSorted = allocator.getAllocableWorkersForLocalRequest( responses, myCertPath, request, allAllocableWorkers); LocalConsumer localConsumer = PeerDAOFactory.getInstance().getConsumerDAO().getLocalConsumer(userPublicKey); for (AllocableWorker allocableWorker : myAllocableWorkersSorted) { dispatchAllocation(responses, request, allocableWorker, localConsumer); } if( request.getNeededWorkers() > 0 ) { forwardToCommunity(responses, requestSpec); if (!myPublicKey.equals(userPublicKey)) { RequestUtils.scheduleRequest(responses, requestSpec); } } if (!isRepetition) { JobControl.getInstance().addRequest(responses, request); } } private void forwardToCommunity(List<IResponseTO> responses, RequestSpecification requestSpec) { CommunityObtainerController.getInstance().request(responses, requestSpec); } private void dispatchAllocation(List<IResponseTO> responses, Request request, AllocableWorker allocableWorker, LocalConsumer localConsumer) { if (allocableWorker.getConsumer() != null) {//preemption String workerManagementAddress = allocableWorker.getWorkerAddress(); LoggerResponseTO loggerResponseTo = new LoggerResponseTO( "Request " + request.getSpecification().getRequestId() + ": Taking worker [" + workerManagementAddress + "] from [" + allocableWorker.getConsumer().getConsumerAddress()+ "]", LoggerResponseTO.INFO); responses.add(loggerResponseTo); if (allocableWorker.getConsumer().isLocal()) { LocalPreemptedWorkerResponseTO to = new LocalPreemptedWorkerResponseTO(); to.setLwpcAddress(allocableWorker.getConsumer().getConsumerAddress()); to.setWorkerAddress(workerManagementAddress); Request loserRequest = allocableWorker.getRequest(); loserRequest.removeAllocableWorker(allocableWorker); RequestSpecification spec = loserRequest.getSpecification(); if (loserRequest.needMoreWorkers() ) { RequestUtils.scheduleRequest(responses, spec); } } else { RemotePreemptedWorkerResponseTO to = new RemotePreemptedWorkerResponseTO(); LocalWorker localWorker = WorkerControl.getInstance().getLocalWorker(responses, StringUtil.addressToUserAtServer(workerManagementAddress)); to.setRwmPublicKey(localWorker.getPublicKey()); } // RegisterInterestResponseTO registerInterestTo = new RegisterInterestResponseTO(); // registerInterestTo.setMonitorName(allocableWorker.getMonitorName()); // registerInterestTo.setMonitorableType(allocableWorker.getMonitorableType()); // registerInterestTo.setMonitorableAddress(workerManagementAddress); // // responses.add(registerInterestTo); } allocableWorker.clear(); allocableWorker.setStatus(LocalWorkerState.IN_USE); if (allocableWorker.isWorkerLocal()) { WorkerControl.getInstance().statusChanged( responses, StringUtil.addressToUserAtServer(allocableWorker.getWorkerAddress()), LocalWorkerState.IN_USE, StringUtil.addressToUserAtServer(localConsumer.getConsumerAddress())); } allocableWorker.setConsumer(localConsumer); allocableWorker.setRequest(request); request.addAllocableWorker(allocableWorker); allocableWorker.workForBroker(responses); } private boolean requestIsRunning(RequestSpecification requestSpec) { return PeerDAOFactory.getInstance().getRequestDAO().isRunning(requestSpec); } private boolean validateRequest(List<IResponseTO> responses, RequestSpecification requestSpec, String userPubKey) { PeerUserReference loggedUser = PeerDAOFactory.getInstance().getUsersDAO().getLoggedUser(userPubKey); if (loggedUser == null) { return false; } String userID = loggedUser.getWorkerProviderClientAddress(); if(requestSpec == null) { LoggerResponseTO loggerResponse = new LoggerResponseTO( RequestMessages.getNullRequestMessage(userID), LoggerResponseTO.WARN); responses.add(loggerResponse); return false; } if(requestSpec.getRequiredWorkers() < 1) { LoggerResponseTO loggerResponse = new LoggerResponseTO( RequestMessages.getRequestWithLessThanOneWorkerMessage(requestSpec, userID), LoggerResponseTO.WARN); responses.add(loggerResponse); return false; } return true; } }