/*
* Copyright 2014 the original author or authors.
*
* 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 de.codecentric.boot.admin.registry;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import de.codecentric.boot.admin.event.ClientApplicationDeregisteredEvent;
import de.codecentric.boot.admin.event.ClientApplicationRegisteredEvent;
import de.codecentric.boot.admin.model.Application;
import de.codecentric.boot.admin.registry.store.ApplicationStore;
/**
* Registry for all applications that should be managed/administrated by the Spring Boot Admin
* application. Backed by an ApplicationStore for persistence and an ApplicationIdGenerator for id
* generation.
*/
public class ApplicationRegistry implements ApplicationEventPublisherAware {
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRegistry.class);
private final ApplicationStore store;
private final ApplicationIdGenerator generator;
private ApplicationEventPublisher publisher;
public ApplicationRegistry(ApplicationStore store, ApplicationIdGenerator generator) {
this.store = store;
this.generator = generator;
}
/**
* Register application.
*
* @param application application to be registered.
* @return the registered application.
*/
public Application register(Application application) {
Assert.notNull(application, "Application must not be null");
Assert.hasText(application.getName(), "Name must not be null");
Assert.hasText(application.getHealthUrl(), "Health-URL must not be null");
Assert.isTrue(checkUrl(application.getHealthUrl()), "Health-URL is not valid");
Assert.isTrue(
StringUtils.isEmpty(application.getManagementUrl())
|| checkUrl(application.getManagementUrl()), "URL is not valid");
Assert.isTrue(
StringUtils.isEmpty(application.getServiceUrl())
|| checkUrl(application.getServiceUrl()), "URL is not valid");
String applicationId = generator.generateId(application);
Assert.notNull(applicationId, "ID must not be null");
Application.Builder builder = Application.copyOf(application).withId(applicationId);
Application existing = getApplication(applicationId);
if (existing != null) {
// Copy Status and Info from existing registration.
builder.withStatusInfo(existing.getStatusInfo()).withInfo(existing.getInfo());
}
Application registering = builder.build();
Application replaced = store.save(registering);
if (replaced == null) {
LOGGER.info("New Application {} registered ", registering);
publisher.publishEvent(new ClientApplicationRegisteredEvent(registering));
} else {
if (registering.getId().equals(replaced.getId())) {
LOGGER.debug("Application {} refreshed", registering);
} else {
LOGGER.warn("Application {} replaced by Application {}", registering, replaced);
}
}
return registering;
}
/**
* Checks the syntax of the given URL.
*
* @param url The URL.
* @return true, if valid.
*/
private boolean checkUrl(String url) {
try {
new URL(url);
} catch (MalformedURLException e) {
return false;
}
return true;
}
/**
* Get a list of all registered applications.
*
* @return List of all applications.
*/
public Collection<Application> getApplications() {
return store.findAll();
}
/**
* Get a list of all registered applications.
*
* @param name the name to search for.
* @return List of applications with the given name.
*/
public Collection<Application> getApplicationsByName(String name) {
return store.findByName(name);
}
/**
* Get a specific application inside the registry.
*
* @param id Id.
* @return Application.
*/
public Application getApplication(String id) {
return store.find(id);
}
/**
* Remove a specific application from registry
*
* @param id the applications id to unregister
* @return the unregistered Application
*/
public Application deregister(String id) {
Application app = store.delete(id);
if (app != null) {
LOGGER.info("Application {} unregistered ", app);
publisher.publishEvent(new ClientApplicationDeregisteredEvent(app));
}
return app;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
publisher = applicationEventPublisher;
}
}