/* * Copyright (C) 2008 Universidade Federal de Campina Grande * * This file is part of OurGrid. * * OurGrid is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package org.ourgrid.peer.business.controller.allocation; 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.response.LoggerResponseTO; import org.ourgrid.common.internal.response.ReleaseResponseTO; import org.ourgrid.common.specification.worker.WorkerSpecification; import org.ourgrid.common.statistics.control.WorkerControl; import org.ourgrid.common.util.StringUtil; import org.ourgrid.peer.business.controller.WorkerNotificationController; import org.ourgrid.peer.business.controller.messages.WorkerMessages; import org.ourgrid.peer.business.dao.PeerDAOFactory; import org.ourgrid.peer.business.util.RequestUtils; import org.ourgrid.peer.dao.AllocationDAO; import org.ourgrid.peer.response.DisposeRemoteWorkerResponseTO; import org.ourgrid.peer.response.StopWorkingResponseTO; import org.ourgrid.peer.to.AllocableWorker; import org.ourgrid.peer.to.LocalAllocableWorker; import org.ourgrid.peer.to.LocalConsumer; import org.ourgrid.peer.to.LocalWorker; import org.ourgrid.peer.to.RemoteAllocableWorker; import org.ourgrid.peer.to.Request; import org.ourgrid.reqtrace.Req; public class RedistributionController { private static RedistributionController instance = null; private RedistributionController() {} public static RedistributionController getInstance() { if (instance == null) { instance = new RedistributionController(); } return instance; } /** * Redistributes a local worker * @param responses * @param allocableWorker * @return true if the local worker was allocated, false if it's idle */ public void redistributeDeliveredWorker(List<IResponseTO> responses, LocalAllocableWorker allocableWorker, LocalWorker localWorker) { Request suitableRequestForWorker = DefaultAllocator.getInstance().getRequestForWorkerSpecification( allocableWorker.getWorkerSpecification()); if(suitableRequestForWorker == null){ StopWorkingResponseTO to = new StopWorkingResponseTO(); to.setWmAddress(allocableWorker.getWorkerAddress()); responses.add(to); return; } allocateRequestToIdleWorker(responses, allocableWorker, suitableRequestForWorker, localWorker); } public boolean redistributeIdleWorker(List<IResponseTO> responses, LocalWorker localWorker) { Request suitableRequestForWorker = DefaultAllocator.getInstance().getRequestForWorkerSpecification( localWorker.getWorkerSpecification()); if(suitableRequestForWorker != null){ AllocationDAO allocationDAO = PeerDAOFactory.getInstance().getAllocationDAO(); AllocableWorker allocableWorker = allocationDAO.getAllocableWorker(localWorker.getPublicKey()); allocateRequestToIdleWorker(responses, allocableWorker, suitableRequestForWorker, localWorker); return true; } return false; } /** * Redistributes a remote worker * @param provider * @param worker * @param workerSpec * @return true if the local worker was allocated, false if it was * disposed to its provider */ public boolean redistributeRemoteWorker(List<IResponseTO> responses, RemoteAllocableWorker allocable) { String workerAddress = allocable.getWorkerAddress(); String workerPublicKey = allocable.getWorkerPubKey(); if (workerAddress == null || !isThereAtLeastOneRequestThatMatchesAndNeedMoreWorkers( PeerDAOFactory.getInstance().getRequestDAO().getRunningRequests(), allocable.getWorkerSpecification())) { String providerAddress = allocable.getProviderAddress(); removeRemoteWorker(responses, workerAddress, providerAddress, workerPublicKey); disposeWorkerToRemoteProvider(responses, workerAddress, providerAddress, workerPublicKey); return false; } Request request = DefaultAllocator.getInstance().getRequestForWorkerSpecification(allocable.getWorkerSpecification()); RemoteAllocableWorker rAlloca = PeerDAOFactory.getInstance().getAllocationDAO().getRemoteAllocableWorker(workerPublicKey); LocalConsumer localConsumer = request.getConsumer(); rAlloca.setConsumer(localConsumer); rAlloca.setRequest(request); request.addAllocableWorker(rAlloca); rAlloca.workForBroker(responses); long requestId = request.getSpecification().getRequestId(); if(!request.needMoreWorkers()) { RequestUtils.cancelScheduledRequest(responses, requestId); } return true; } /** * Redistributes an AllocableWorker * @param allocable */ @Req({"REQ015", "REQ016"}) public void redistributeWorker(List<IResponseTO> responses, AllocableWorker allocable) { RequestSpecification requestSpecification = allocable.getRequest().getSpecification(); allocable.deallocate(); if(allocable.isWorkerLocal()){ LocalWorker localWorker = ((LocalAllocableWorker) allocable).getLocalWorker(); redistributeLocalWorker(responses, localWorker, (LocalAllocableWorker) allocable); } else { RemoteAllocableWorker rAllocable = (RemoteAllocableWorker) allocable; redistributeRemoteWorker(responses, rAllocable); } Request request = PeerDAOFactory.getInstance().getRequestDAO().getRequest( requestSpecification.getRequestId()); if (request != null && request.needMoreWorkers()) { scheduleRequest(responses, requestSpecification); } } private void removeRemoteWorker(List<IResponseTO> responses, String workerAddress, String providerAddress, String workerPublicKey) { WorkerControl.getInstance().removeRemoteWorker(responses, StringUtil.addressToUserAtServer(workerAddress)); PeerDAOFactory.getInstance().getAllocationDAO().removeRemoteAllocableWorker(workerPublicKey); ReleaseResponseTO releaseTO = new ReleaseResponseTO(); releaseTO.setStubAddress(workerAddress); responses.add(releaseTO); } private void disposeWorkerToRemoteProvider(List<IResponseTO> responses, String workerAddress, String providerAddress, String workerPublicKey) { boolean providerIsUp = providerAddress != null; if (providerIsUp) { responses.add(new LoggerResponseTO(WorkerMessages.getDisposingWorkerToRemoteProviderMessage( providerAddress, workerAddress), LoggerResponseTO.DEBUG)); DisposeRemoteWorkerResponseTO to = new DisposeRemoteWorkerResponseTO(); to.setProviderAddress(providerAddress); to.setWorkerAddress(workerAddress); to.setWorkerPublicKey(workerPublicKey); responses.add(to); } } private boolean isThereAtLeastOneRequestThatMatchesAndNeedMoreWorkers( List<Request> requests, WorkerSpecification spec) { for (Request request : requests) { if (Util.matchAndNeedWorkers(spec, request)) { return true; } } return false; } @Req("REQ117") public LocalAllocableWorker createAllocableWorker(LocalWorker localWorker, String localWorkerProviderAddress, String myCertPathDN) { AllocationDAO allocationDAO = PeerDAOFactory.getInstance().getAllocationDAO(); /*LocalWorkerProvider localWorkerProvider = (LocalWorkerProvider) serviceManager.getObjectDeployment( PeerConstants.LOCAL_WORKER_PROVIDER).getObject(); String myCertPathDN = CertificationUtils.getCertSubjectDN(serviceManager.getMyCertPath()); LocalAllocableWorker allocableWorker = new LocalAllocableWorker(localWorker, localWorkerProvider,myCertPathDN);*/ LocalAllocableWorker allocableWorker = new LocalAllocableWorker(localWorker, localWorkerProviderAddress, myCertPathDN); allocationDAO.addLocalAllocableWorker(localWorker.getPublicKey(), allocableWorker); return allocableWorker; } @Req("REQ117") private void allocateRequestToIdleWorker(List<IResponseTO> responses, AllocableWorker allocableWorker, Request request, LocalWorker localWorker) { localWorker.setStatus(LocalWorkerState.IN_USE); WorkerControl.getInstance().statusChanged(responses, localWorker.getWorkerUserAtServer(), LocalWorkerState.IN_USE); LocalConsumer localConsumer = request.getConsumer(); allocableWorker.setConsumer(localConsumer); allocableWorker.setRequest(request); request.addAllocableWorker(allocableWorker); allocableWorker.workForBroker(responses); if(!request.needMoreWorkers()){ RequestUtils.cancelScheduledRequest(responses, request.getSpecification().getRequestId()); } } /** * @param requestSpec */ private void scheduleRequest(List<IResponseTO> responses, RequestSpecification requestSpec) { RequestUtils.scheduleRequest(responses, requestSpec); } @Req("REQ015") private void redistributeLocalWorker(List<IResponseTO> responses, LocalWorker localWorker, LocalAllocableWorker allocableWorker) { redistributeDeliveredWorker(responses, allocableWorker, localWorker); // RegisterInterestResponseTO registerInterestResponse = new RegisterInterestResponseTO(); // registerInterestResponse.setMonitorableAddress(allocableWorker.getWorkerAddress()); // registerInterestResponse.setMonitorableType(WorkerManagement.class); // registerInterestResponse.setMonitorName(PeerConstants.WORKER_MANAGEMENT_CLIENT_OBJECT_NAME); // // responses.add(registerInterestResponse); } }