001/**
002 * Copyright 2005-2018 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.ksb.impl.registry;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.criteria.QueryByCriteria;
020import org.kuali.rice.core.api.criteria.QueryResults;
021import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
022import org.kuali.rice.krad.data.DataObjectService;
023import org.kuali.rice.ksb.api.registry.RemoveAndPublishResult;
024import org.kuali.rice.ksb.api.registry.ServiceDescriptor;
025import org.kuali.rice.ksb.api.registry.ServiceEndpoint;
026import org.kuali.rice.ksb.api.registry.ServiceEndpointStatus;
027import org.kuali.rice.ksb.api.registry.ServiceInfo;
028import org.kuali.rice.ksb.api.registry.ServiceRegistry;
029import org.springframework.beans.factory.annotation.Required;
030
031import javax.xml.namespace.QName;
032import java.util.ArrayList;
033import java.util.Collections;
034import java.util.List;
035
036import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
037
038/**
039 * Reference implementation of the {@link ServiceRegistry} which is backed by a
040 * data access object that handles reading and writing data related to registry
041 * entries from a backend datastore.
042 *
043 * @author Kuali Rice Team (rice.collab@kuali.org)
044 *
045 */
046public class ServiceRegistryImpl implements ServiceRegistry {
047
048    private DataObjectService dataObjectService;
049
050        @Override
051        public List<ServiceInfo> getOnlineServicesByName(QName serviceName)
052                        throws RiceIllegalArgumentException {
053                if (serviceName == null) {
054                        throw new RiceIllegalArgumentException("serviceName cannot be null");
055                }
056
057        QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
058        builder.setPredicates(equal("serviceName",serviceName.toString()),
059                                equal("statusCode",ServiceEndpointStatus.ONLINE.getCode()));
060                List<ServiceInfoBo> serviceInfoBos = getDataObjectService().findMatching(
061                ServiceInfoBo.class,builder.build()).getResults();
062                return convertServiceInfoBoList(serviceInfoBos);
063        }
064
065        @Override
066        public List<ServiceInfo> getAllOnlineServices() {
067        QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
068        builder.setPredicates(equal("statusCode",ServiceEndpointStatus.ONLINE.getCode()));
069        List<ServiceInfoBo> serviceInfoBos = getDataObjectService().findMatching(
070                ServiceInfoBo.class,builder.build()).getResults();
071                return convertServiceInfoBoList(serviceInfoBos);
072        }
073        
074        @Override
075        public List<ServiceInfo> getAllServices() {
076        QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
077        List<ServiceInfoBo> serviceInfoBos = getDataObjectService().findMatching(
078                ServiceInfoBo.class,builder.build()).getResults();
079                return convertServiceInfoBoList(serviceInfoBos);
080        }
081        
082        @Override
083        public List<ServiceInfo> getAllServicesForInstance(String instanceId) throws RiceIllegalArgumentException {
084                if (StringUtils.isBlank(instanceId)) {
085                        throw new RiceIllegalArgumentException("instanceId cannot be blank");
086                }
087        QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
088        builder.setPredicates(equal("instanceId",instanceId));
089        List<ServiceInfoBo> serviceInfoBos = getDataObjectService().findMatching(
090                ServiceInfoBo.class,builder.build()).getResults();
091                return convertServiceInfoBoList(serviceInfoBos);
092        }
093
094    @Override
095    public List<ServiceInfo> getAllServicesForApplication(String applicationId) throws RiceIllegalArgumentException {
096        if (StringUtils.isBlank(applicationId)) {
097            throw new RiceIllegalArgumentException("applicationId cannot be blank");
098        }
099        QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
100        builder.setPredicates(equal("applicationId",applicationId));
101        List<ServiceInfoBo> serviceInfoBos = getDataObjectService().findMatching(
102                ServiceInfoBo.class,builder.build()).getResults();
103        return convertServiceInfoBoList(serviceInfoBos);
104    }
105
106        @Override
107        public ServiceDescriptor getServiceDescriptor(String serviceDescriptorId)
108                        throws RiceIllegalArgumentException {
109                if (StringUtils.isBlank(serviceDescriptorId)) {
110                        throw new RiceIllegalArgumentException("serviceDescriptorId cannot be blank");
111                }
112                ServiceDescriptorBo serviceDescriptorBo = getDataObjectService().find(
113                ServiceDescriptorBo.class,serviceDescriptorId);
114                return ServiceDescriptorBo.to(serviceDescriptorBo);
115        }
116
117        @Override
118        public List<ServiceDescriptor> getServiceDescriptors(List<String> serviceDescriptorIds)
119                        throws RiceIllegalArgumentException {
120                if (serviceDescriptorIds == null) {
121                        throw new RiceIllegalArgumentException("serviceDescriptorIds cannot be null");
122                }
123                List<ServiceDescriptor> serviceDescriptors = new ArrayList<ServiceDescriptor>();
124                for (String serviceDescriptorId : serviceDescriptorIds) {
125                        ServiceDescriptor serviceDescriptor = getServiceDescriptor(serviceDescriptorId);
126                        if (serviceDescriptor != null) {
127                                serviceDescriptors.add(serviceDescriptor);
128                        }
129                }
130                return Collections.unmodifiableList(serviceDescriptors);
131        }
132
133        @Override
134        public ServiceEndpoint publishService(ServiceEndpoint serviceEndpoint)
135                        throws RiceIllegalArgumentException {
136                if (serviceEndpoint == null) {
137                        throw new RiceIllegalArgumentException("serviceEndpoint cannot be null");
138                }
139                ServiceDescriptor serviceDescriptor = serviceEndpoint.getDescriptor();
140                ServiceDescriptorBo serviceDescriptorBo = ServiceDescriptorBo.from(serviceDescriptor);
141                ServiceInfo serviceInfo = serviceEndpoint.getInfo();
142                ServiceInfoBo serviceInfoBo = ServiceInfoBo.from(serviceInfo);
143                serviceDescriptorBo = getDataObjectService().save(serviceDescriptorBo);
144                serviceInfoBo.setServiceDescriptorId(serviceDescriptorBo.getId());
145        serviceInfoBo = getDataObjectService().save(serviceInfoBo);
146                
147                
148                return ServiceEndpoint.Builder.create(ServiceInfo.Builder.create(serviceInfoBo),
149                                ServiceDescriptor.Builder.create(serviceDescriptorBo)).build();
150        }
151
152        @Override
153        public List<ServiceEndpoint> publishServices(List<ServiceEndpoint> serviceEndpoints)
154                        throws RiceIllegalArgumentException {
155                if (serviceEndpoints == null) {
156                        throw new RiceIllegalArgumentException("serviceEndpoints cannot be null");
157                }
158                List<ServiceEndpoint> publishedEndpoints = new ArrayList<ServiceEndpoint>();
159                for (ServiceEndpoint serviceEndpoint : serviceEndpoints) {
160                        publishedEndpoints.add(publishService(serviceEndpoint));
161                }
162                return publishedEndpoints;
163        }
164
165        @Override
166        public ServiceEndpoint removeServiceEndpoint(String serviceId)
167                        throws RiceIllegalArgumentException {
168                if (StringUtils.isBlank(serviceId)) {
169                        throw new RiceIllegalArgumentException("serviceId cannot be blank");
170                }
171                ServiceInfoBo serviceInfoBo = getDataObjectService().find(ServiceInfoBo.class, serviceId);
172                if (serviceInfoBo != null) {
173                        ServiceDescriptorBo serviceDescriptorBo = getDataObjectService().find(
174                    ServiceDescriptorBo.class,serviceInfoBo.getServiceDescriptorId());
175            if(serviceDescriptorBo != null) {
176                ServiceEndpoint endpointPriorRemoval = ServiceEndpoint.Builder.create(ServiceInfo.Builder.create(serviceInfoBo),
177                        ServiceDescriptor.Builder.create(serviceDescriptorBo)).build();
178
179                QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
180                builder.setPredicates(equal("serviceId",serviceInfoBo.getServiceId()));
181                getDataObjectService().deleteMatching(ServiceInfoBo.class,builder.build());
182
183                builder = QueryByCriteria.Builder.create();
184                builder.setPredicates(equal("id",serviceInfoBo.getServiceDescriptorId()));
185                getDataObjectService().deleteMatching(ServiceDescriptorBo.class,builder.build());
186                return endpointPriorRemoval;
187           }else{
188                QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
189                builder.setPredicates(equal("serviceId",serviceInfoBo.getServiceId()));
190                getDataObjectService().deleteMatching(ServiceInfoBo.class,builder.build());
191           }
192                }
193                return null;
194        }
195
196        @Override
197        public List<ServiceEndpoint> removeServiceEndpoints(List<String> serviceIds)
198                        throws RiceIllegalArgumentException {
199                if (serviceIds == null) {
200                        throw new RiceIllegalArgumentException("serviceIds canot be null");
201                }
202                List<ServiceEndpoint> servicesRemoved = new ArrayList<ServiceEndpoint>();
203                for (String serviceId : serviceIds) {
204                        servicesRemoved.add(removeServiceEndpoint(serviceId));
205                }
206                return servicesRemoved;
207        }
208
209        @Override
210        public RemoveAndPublishResult removeAndPublish(List<String> removeServiceIds,
211                        List<ServiceEndpoint> publishServiceEndpoints) {
212                List<ServiceEndpoint> servicesRemoved = new ArrayList<ServiceEndpoint>();
213                List<ServiceEndpoint> servicesPublished = new ArrayList<ServiceEndpoint>();
214                if (removeServiceIds != null && !removeServiceIds.isEmpty()) {
215                        servicesRemoved = removeServiceEndpoints(removeServiceIds);
216                }
217                if (publishServiceEndpoints != null && !publishServiceEndpoints.isEmpty()) {
218                        servicesPublished = publishServices(publishServiceEndpoints);
219                }
220                return RemoveAndPublishResult.create(servicesRemoved, servicesPublished);
221        }
222
223        @Override
224        public boolean updateStatus(String serviceId, ServiceEndpointStatus status) throws RiceIllegalArgumentException {
225                if (StringUtils.isBlank(serviceId)) {
226                        throw new RiceIllegalArgumentException("serviceId cannot be blank");
227                }
228                if (status == null) {
229                        throw new RiceIllegalArgumentException("status cannot be null");
230                }
231        ServiceInfoBo serviceInfoBo = getDataObjectService().find(ServiceInfoBo.class,serviceId);
232        if (serviceInfoBo == null) {
233            return false;
234        }
235        serviceInfoBo.setStatusCode(status.getCode());
236        getDataObjectService().save(serviceInfoBo);
237        return true;
238        }
239
240        @Override
241        public List<String> updateStatuses(List<String> serviceIds, ServiceEndpointStatus status) throws RiceIllegalArgumentException {
242                if (serviceIds == null) {
243                        throw new RiceIllegalArgumentException("serviceIds canot be null");
244                }
245                if (status == null) {
246                        throw new RiceIllegalArgumentException("status cannot be null");
247                }
248                List<String> updatedServiceIds = new ArrayList<String>();
249                for (String serviceId : serviceIds) {
250                        if (updateStatus(serviceId, status)) {
251                                updatedServiceIds.add(serviceId);
252                        }
253                }
254                return Collections.unmodifiableList(updatedServiceIds);
255        }
256
257        @Override
258        public void takeInstanceOffline(String instanceId)
259                        throws RiceIllegalArgumentException {
260                if (StringUtils.isBlank(instanceId)) {
261                        throw new RiceIllegalArgumentException("instanceId cannot be blank");
262                }
263        QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
264        builder.setPredicates(equal("instanceId", instanceId));
265        QueryResults<ServiceInfoBo> results = getDataObjectService().findMatching(ServiceInfoBo.class, builder.build());
266        for (ServiceInfoBo serviceInfo : results.getResults()) {
267            serviceInfo.setStatusCode(ServiceEndpointStatus.OFFLINE.getCode());
268            getDataObjectService().save(serviceInfo);
269        }
270        }
271
272        private List<ServiceInfo> convertServiceInfoBoList(List<ServiceInfoBo> serviceInfoBos) {
273                List<ServiceInfo> serviceInfos = new ArrayList<ServiceInfo>();
274                if (serviceInfoBos != null) {
275                        for (ServiceInfoBo serviceInfoBo : serviceInfoBos) {
276                                serviceInfos.add(ServiceInfoBo.to(serviceInfoBo));
277                        }
278                } else {
279                        return Collections.emptyList();
280                }
281                return Collections.unmodifiableList(serviceInfos);
282        }
283
284    public DataObjectService getDataObjectService() {
285        return dataObjectService;
286    }
287
288    @Required
289    public void setDataObjectService(DataObjectService dataObjectService) {
290        this.dataObjectService = dataObjectService;
291    }
292
293
294
295}