Java tutorial
/* * 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 org.apache.karaf.cellar.cloud; import org.apache.karaf.cellar.core.discovery.DiscoveryService; import org.jclouds.ContextBuilder; import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.domain.StorageType; import org.jclouds.blobstore.options.ListContainerOptions; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * Discovery service that use a cloud blob store. */ public class BlobStoreDiscoveryService implements DiscoveryService { private static final transient Logger LOGGER = LoggerFactory.getLogger(BlobStoreDiscoveryService.class); private String provider; private String identity; private String credential; private String container; private Integer validityPeriod = 60; private String ipAddress = getIpAddress(); BlobStoreContext context; private BlobStore blobStore; public BlobStoreDiscoveryService() { LOGGER.debug("CELLAR CLOUD: blob store discovery service initialized"); } public void init() { try { if (blobStore == null) { if (context == null) { context = ContextBuilder.newBuilder(provider).credentials(identity, credential) .buildView(BlobStoreContext.class); } blobStore = context.getBlobStore(); signIn(); } } catch (Exception ex) { LOGGER.error("CELLAR CLOUD: error while initializing blob store discovery service", ex); } } public void destroy() { signOut(); context.close(); } public void update(Map<String, Object> properties) { LOGGER.debug("CELLAR CLOUD: updating properties"); } /** * Returns a {@link Set} of IPs. * * @return a set of IPs. */ @Override public Set<String> discoverMembers() { refresh(); Set<String> members = new HashSet<String>(); ListContainerOptions opt = new ListContainerOptions(); PageSet<? extends StorageMetadata> pageSet = blobStore.list(container, opt); LOGGER.debug("CELLAR CLOUD: storage contains a page set of size {}", pageSet.size()); for (StorageMetadata md : pageSet) { if (md.getType() != StorageType.BLOB) { //skip everything that isn't of type BLOB ... continue; } String ip = md.getName(); Object obj = readBlob(container, ip); if (obj == null) { LOGGER.debug("CELLAR CLOUD: no valid object found, skipping it"); continue; } // check if the IP hasn't been updated recently if (obj instanceof DateTime) { LOGGER.debug("CELLAR CLOUD: retrieved a DateTime from blog store"); DateTime registeredTime = (DateTime) obj; if (registeredTime != null && registeredTime.plusSeconds(validityPeriod).isAfterNow()) { LOGGER.debug("CELLAR CLOUD: adding member {}", ip); members.add(ip); } else { LOGGER.debug("CELLAR CLOUD: remove container {}", ip); blobStore.removeBlob(container, ip); } } else if (obj instanceof ServiceContainer) { LOGGER.debug("CELLAR CLOUD: retrieved a ServiceContainer from blog store"); ServiceContainer serviceContainer = (ServiceContainer) obj; DateTime registeredTime = serviceContainer.getRegisteredTime(); if (registeredTime != null && registeredTime.plusSeconds(validityPeriod).isAfterNow()) { LOGGER.debug("CELLAR CLOUD: adding member {} for IP {}", serviceContainer.getHostName(), ip); members.add(serviceContainer.getHostIp()); } else { LOGGER.debug("CELLAR CLOUD: remove container {}", ip); blobStore.removeBlob(container, ip); } } } LOGGER.debug("CELLAR CLOUD: returning members {}", members); return members; } /** * Sign In member to the {@link DiscoveryService}. */ @Override public void signIn() { DateTime now = new DateTime(); createBlob(container, ipAddress, new ServiceContainer(getHostName(), getIpAddress(), now)); } /** * Refresh member to the {@link DiscoveryService}. */ @Override public void refresh() { DateTime now = new DateTime(); createBlob(container, ipAddress, new ServiceContainer(getHostName(), getIpAddress(), now)); } /** * Sign out member to the {@link DiscoveryService}. */ @Override public void signOut() { if (blobStore.blobExists(container, ipAddress)) { blobStore.removeBlob(container, ipAddress); } else { LOGGER.debug("CELLAR CLOUD: could not find the IP address of the current node in the blob store"); } } /** * Reads from a {@link BlobStore}. * * @param container the blob store container. * @param blobName the blob store name. * @return the Object read from the blob store. */ protected Object readBlob(String container, String blobName) { Object result = null; ObjectInputStream ois = null; blobStore.createContainerInLocation(null, container); InputStream is = blobStore.getBlob(container, blobName).getPayload().getInput(); try { ois = new ObjectInputStream(is); result = ois.readObject(); } catch (IOException e) { LOGGER.warn("CELLAR CLOUD: error while reading blob", e); } catch (ClassNotFoundException e) { LOGGER.warn("CELLAR CLOUD: error while reading blob", e); } finally { if (ois != null) { try { ois.close(); } catch (IOException e) { // nothing to do } } if (is != null) { try { is.close(); } catch (IOException e) { // nothing to do } } } return result; } /** * Create a blob store. * * @param container the blob store container. * @param name the blob store name. * @param data the blob store data. */ public void createBlob(String container, String name, Object data) { Blob blob; if (blobStore != null) { if (!blobStore.containerExists(container)) { blobStore.createContainerInLocation(null, container); } if (blobStore.blobExists(container, name)) { blob = blobStore.getBlob(container, name); } else { blob = blobStore.blobBuilder(name).build(); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(baos); oos.writeObject(data); blob.setPayload(baos.toByteArray()); blobStore.putBlob(container, blob); } catch (IOException e) { LOGGER.error("CELLAR CLOUD: error while writing blob", e); } finally { if (oos != null) { try { oos.close(); } catch (IOException e) { // nothing to do } } if (baos != null) { try { baos.close(); } catch (IOException e) { // nothing to do } } } } } /** * Get the IP address of the local node. * * @return the IP address of the local node. */ protected String getIpAddress() { try { return InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException ex) { LOGGER.error("CELLAR CLOUD: can't determine IP address of the local node", ex); return null; } } /** * Get the hostname of the local node. * * @return the hostname of the local node. */ protected String getHostName() { try { return InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException ex) { LOGGER.error("CELLAR CLOUD: unable to determine host name of the node", ex); return null; } } public String getProvider() { return provider; } public void setProvider(String provider) { this.provider = provider; } public String getIdentity() { return identity; } public void setIdentity(String identity) { this.identity = identity; } public String getCredential() { return credential; } public void setCredential(String credential) { this.credential = credential; } public String getContainer() { return container; } public void setContainer(String container) { this.container = container; } public Integer getValidityPeriod() { return validityPeriod; } public void setValidityPeriod(Integer validityPeriod) { this.validityPeriod = validityPeriod; } }