You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by rj...@apache.org on 2009/06/09 14:00:32 UTC
svn commit: r782968 [3/7] - in /directory/sandbox/slp: ./
src/main/java/org/apache/directory/slp/
src/main/java/org/apache/directory/slp/codec/
src/main/java/org/apache/directory/slp/extensions/
src/main/java/org/apache/directory/slp/impl/ src/main/jav...
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/AttributeListExtension.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/AttributeListExtension.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/AttributeListExtension.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/AttributeListExtension.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.extensions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.impl.AuthenticationBlock;
+import org.apache.directory.slp.impl.SLPCore;
+import org.apache.directory.slp.impl.SLPUtils;
+import org.apache.mina.core.buffer.IoBuffer;
+
+
+/**
+ * The attribute list extension for SLP as described in rfc 3059
+ *
+ * @author Lorenz Breu
+ */
+public class AttributeListExtension extends AbstractExtension{
+
+
+ /*The format of the Attribute List Extension is as follows:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Extension ID = 0x0002 | Next Extension Offset |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Offset, contd.| Service URL Length | Service URL /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Attribute List Length | Attribute List /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |# of AttrAuths |-(if present) Attribute Authentication Blocks.../
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ The Extension ID is 0x0002.
+ */
+
+
+
+
+ private int nextExtensionOffset;
+
+ private String url;
+
+ private String attributeList;
+
+ private AuthenticationBlock[] authBlocks = new AuthenticationBlock[]{};
+
+ public AttributeListExtension(){
+ super(ATTRIBUTE_LIST_EXTENSION);
+ }
+
+ public AttributeListExtension(String url, String attributes){
+ super(ATTRIBUTE_LIST_EXTENSION);
+ this.url = url;
+ this.attributeList = attributes;
+ }
+
+ public void setNextExtensionOffset(int neo){
+ nextExtensionOffset = neo;
+ }
+
+ public int getNextExtensionOffset(){
+ return nextExtensionOffset;
+ }
+
+ public void setUrl(String serviceUrl){
+ url = serviceUrl;
+ }
+
+
+ public String getUrl(){
+ return url;
+ }
+
+ public void setAttributeList(String attributeList){
+ this.attributeList = attributeList;
+ }
+
+ public String getAttributeList(){
+ return attributeList;
+ }
+
+ public void setAuthenticationBlocks(AuthenticationBlock[] authenticationBlocks){
+ authBlocks = authenticationBlocks;
+ }
+
+ public AuthenticationBlock[] getAuthenticationBlocks() {
+ return authBlocks;
+ }
+
+
+ @Override
+ public int getLength(){
+ int authLength = 0;
+ for (AuthenticationBlock ab : authBlocks){
+ authLength+=ab.getLength();
+ }
+ return (2 + 3 + 2 + url.length() + 2 + attributeList.length() + 1 + authLength);
+ }
+
+
+ protected void decodeBody(final IoBuffer buf, final short id, final int nextOffset) throws Exception{
+ url = decodeString(buf);
+ attributeList = decodeString(buf);
+ authBlocks=decodeAuthBlocks(buf);
+ }
+
+ public void encodeBody(IoBuffer buf){
+ try {
+ encodeString(buf, url);
+ encodeString(buf, attributeList);
+ encodeAuthBlocks(authBlocks, buf);
+ } catch (Exception e){
+ SLPCore.getPlatform().logDebug("[Extensions]: Error encoding an Attribute List Extension: " + e.getMessage());
+ }
+ }
+
+
+ /**
+ * 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Block
+ * Structure Descriptor | Authentication Block Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ * Timestamp |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SLP
+ * SPI String Length | SLP SPI String \
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ * Structured Authentication Block ... \
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * @param session
+ * @param in
+ * @return
+ */
+ protected final AuthenticationBlock[] decodeAuthBlocks(final IoBuffer in) throws Exception {
+ final short blocks = (short) in.get();
+ final AuthenticationBlock[] result = new AuthenticationBlock[blocks];
+ for (int i = 0; i < blocks; i++) {
+ final short bsd = (short) in.getShort();
+ if (bsd != AuthenticationBlock.BSD_DSA) {
+ throw new ServiceLocationException(
+ ServiceLocationException.AUTHENTICATION_FAILED, "BSD "
+ + bsd + " is not supported.");
+ }
+ final int size = in.getShort();
+ final int timestamp = in.getInt();
+ final String spi = decodeString(in);
+ final byte[] sig = new byte[size - 2 - 2 - 4 - 2
+ - spi.getBytes().length];
+ in.get(sig);
+ result[i] = new AuthenticationBlock(timestamp, spi, sig);
+ }
+
+ // return SLPCore.CONFIG.getSecurityEnabled() ? result
+ // : new AuthenticationBlock[0];
+ return result;
+ }
+
+ protected final void encodeAuthBlocks(
+ final AuthenticationBlock[] authBlocks,
+ final IoBuffer out) throws Exception {
+ // FIXME: hack
+ if (authBlocks == null) {
+ out.put((byte) 0);
+ return;
+ }
+ out.put((byte) authBlocks.length);
+ for (int i = 0; i < authBlocks.length; i++) {
+ final int pos = out.position();
+ out.putShort(AuthenticationBlock.BSD_DSA); // BSD
+ out.skip(2); // skip the length field
+ out.putInt(authBlocks[i].getTimestamp());
+ encodeString(out, authBlocks[i].getSpi());
+ out.put(authBlocks[i].getSig());
+ // fill in the length
+ out.putShort(pos + 2, (short) (out.position() - pos));
+ }
+ }
+
+
+ public void sign(final String spiStr) throws ServiceLocationException {
+ List spiList = SLPUtils.stringToList(spiStr, ",");
+ authBlocks = new AuthenticationBlock[spiList.size()];
+ for (int k = 0; k < spiList.size(); k++) {
+ int timestamp = SLPUtils.getTimestamp();
+
+ String spi = (String) spiList.get(k);
+ byte[] data = getAuthData(spi, timestamp);
+ byte[] sig;
+ try {
+ sig = AuthenticationBlock.sign(spi,data);
+ } catch (Exception e) {
+ //SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
+ throw new ServiceLocationException(
+ ServiceLocationException.AUTHENTICATION_FAILED,
+ "Could not sign data");
+ }
+
+
+ authBlocks[k] = new AuthenticationBlock(timestamp,spi,sig);
+ }
+ }
+
+ public boolean verify() {
+ try {
+ for (int i = 0; i < authBlocks.length; i++) {
+
+ if (authBlocks[i].verify(getAuthData(authBlocks[i].getSpi(),
+ authBlocks[i].getTimestamp()))) {
+ return true;
+ }
+ }
+ return false;
+ } catch (ServiceLocationException sle){
+ return false;
+ }
+ }
+
+
+ private byte[] getAuthData(final String spiStr, final int timestamp)
+ throws ServiceLocationException {
+try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(bos);
+ dos.writeUTF(spiStr);
+ dos.writeUTF(attributeList);
+ dos.writeInt(timestamp);
+ return bos.toByteArray();
+} catch (IOException ioe) {
+ throw new ServiceLocationException(
+ ServiceLocationException.INTERNAL_SYSTEM_ERROR, ioe
+ .getMessage());
+}
+}
+
+
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/AttributeListExtension.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SelectExtension.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SelectExtension.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SelectExtension.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SelectExtension.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.extensions;
+
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.impl.SLPCore;
+import org.apache.mina.core.buffer.IoBuffer;
+
+
+
+/**
+ * The select extension as defined in RFC 3421
+ *
+ * (processing currently not yet implemented)
+ *
+ * @author Lorenz Breu
+ */
+public class SelectExtension extends AbstractExtension{
+
+
+ /*
+ * 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Select Extension ID = 0x4002 | Next Extension Offset (NEO) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | NEO, cont'd | Number of URL Entries |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+
+ // The number of entries to be returned
+ private short numberOfEntries = 0;
+
+ public SelectExtension(){
+ super(SELECT_EXTENSION);
+ }
+
+ public SelectExtension(short n){
+ super(SELECT_EXTENSION);
+ numberOfEntries = n;
+ }
+
+ @Override
+ protected void decodeBody(IoBuffer buf, short id, int nextOffset) throws Exception {
+ numberOfEntries = buf.getShort();
+
+ }
+
+ @Override
+ public void encodeBody(IoBuffer buf) {
+ try {
+ buf.putShort(numberOfEntries);
+ } catch (Exception e){
+ SLPCore.getPlatform().logDebug("[Extensions]: Error encoding a Select Extension: " + e.getMessage());
+ }
+
+ }
+
+ @Override
+ public void sign(String spi) throws ServiceLocationException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean verify() {
+ return true;
+ }
+
+ public short getNumberOfEntries() {
+ return numberOfEntries;
+ }
+
+ public void setNumberOfEntries(short numberOfEntries) {
+ this.numberOfEntries = numberOfEntries;
+ }
+
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SelectExtension.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SortExtension.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SortExtension.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SortExtension.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SortExtension.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.extensions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.impl.SLPCore;
+import org.apache.directory.slp.impl.SLPUtils;
+import org.apache.mina.core.buffer.IoBuffer;
+
+
+/**
+ * The sort extension as defined in RFC 3421
+ *
+ * (processing currently not yet implemented)
+ *
+ * @author Lorenz Breu
+ */
+public class SortExtension extends AbstractExtension{
+
+ /*
+ * 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Sort Extension ID = 0x4003 | Next Extension Offset (NEO) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | NEO, cont'd | length of <sort-key-list> |<sort-key-list>\
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+ // The key list for sorting
+ private List<String> sortKeyList = new ArrayList<String>();
+
+ public SortExtension(){
+ super(SORT_EXTENSION);
+ }
+
+ public SortExtension(String sortKeyList){
+ super(SORT_EXTENSION);
+ this.sortKeyList = SLPUtils.stringToList(sortKeyList, ",");
+ }
+
+ @Override
+ protected void decodeBody(IoBuffer buf, short id, int nextOffset) throws Exception {
+ sortKeyList = SLPUtils.stringToList(decodeString(buf), ",");
+
+ }
+
+ @Override
+ public void encodeBody(IoBuffer buf) {
+ try{
+ encodeString(buf, SLPUtils.arrayToString(SLPUtils.listToStringArray(sortKeyList),","));
+ } catch (Exception e){
+ SLPCore.getPlatform().logDebug("[Extensions]: Error encoding a Sort Extension: " + e.getMessage());
+ }
+ }
+
+ @Override
+ public void sign(String spi) throws ServiceLocationException {
+ return;
+
+ }
+
+ @Override
+ public boolean verify() {
+ return true;
+ }
+
+ public List<String> getSortKeyList() {
+ return sortKeyList;
+ }
+
+ public void setSortKeyList(List<String> sortKeyList) {
+ this.sortKeyList = sortKeyList;
+ }
+
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SortExtension.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/UnsupportedExtension.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/UnsupportedExtension.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/UnsupportedExtension.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/UnsupportedExtension.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.extensions;
+
+import org.apache.mina.core.buffer.IoBuffer;
+
+/**
+ * A placeholder for extensions that are received but not supported
+ *
+ * @author Lorenz Breu
+ */
+public class UnsupportedExtension extends AbstractExtension{
+
+ public UnsupportedExtension(short id){
+ super(id);
+ }
+
+ @Override
+ protected void decodeBody(IoBuffer buf, short id, int nextOffset) throws Exception {
+
+
+ }
+
+ @Override
+ public void encodeBody(IoBuffer buf) {
+
+
+ }
+
+
+ public boolean verify(){
+ return true;
+ }
+
+ public void sign(String spi){
+
+ }
+
+
+
+
+
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/UnsupportedExtension.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/Activator.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/Activator.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/Activator.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/Activator.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.impl;
+
+import org.apache.directory.slp.ServiceStore;
+import org.apache.directory.slp.impl.da.DirectoryAgentImpl;
+import org.apache.directory.slp.impl.da.SimpleServiceStore;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Bundle Activator
+ *
+ * @author Jan S. Rellermeyer
+ */
+public class Activator implements BundleActivator {
+
+ /**
+ *
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(final BundleContext context) throws Exception {
+
+ // create the platform abstraction layer but do not initialize!!!
+ SLPCore.platform = new OSGiPlatformAbstraction(context);
+
+ // register the service factories so each consumer gets its own Locator/Activator instance
+ context.registerService("ch.ethz.iks.slp.Advertiser", new ServiceFactory() {
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ SLPCore.initSA();
+ return new AdvertiserImpl();
+ }
+ public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+ }
+ }, null);
+ context.registerService("ch.ethz.iks.slp.Locator", new ServiceFactory() {
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ SLPCore.init();
+ return new LocatorImpl();
+ }
+ public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+ }
+ }, null);
+
+
+
+
+ final ServiceStore finalStore = new SimpleServiceStore();
+ context.registerService("ch.ethz.iks.slp.DirectoryAgent", new ServiceFactory() {
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ SLPCore.initDA(finalStore);
+ return new DirectoryAgentImpl();
+ }
+ public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+ }
+ }, null);
+
+
+// context.registerService("ch.ethz.iks.slp.DirectoryAgent", new ServiceFactory() {
+// public Object getService(Bundle bundle, ServiceRegistration registration) {
+// SLPCore.initDA(new SimpleServiceStore());
+// return new DirectoryAgentImpl();
+// }
+// public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+// }
+// }, null);
+ }
+
+ /**
+ *
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(final BundleContext context) throws Exception {
+
+ }
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/Activator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AdvertiserImpl.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AdvertiserImpl.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AdvertiserImpl.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AdvertiserImpl.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,345 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.impl;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.directory.slp.Advertiser;
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.ServiceURL;
+import org.apache.directory.slp.messages.ServiceAcknowledgementMessage;
+import org.apache.directory.slp.messages.ServiceDeregistrationMessage;
+import org.apache.directory.slp.messages.ServiceRegistrationMessage;
+
+/**
+ * Implementation of the Advertiser that provides SLP SA functionality. If the
+ * configuration does not have to support SA functionalities, this class does
+ * not have to be included in the distribution.
+ *
+ * @author Jan S. Rellermeyer
+ */
+public final class AdvertiserImpl implements Advertiser {
+
+ /**
+ * the locale of this instance. Will be used for all messages created by
+ * this Advertiser instance.
+ */
+ private Locale locale;
+
+ /**
+ * Constructor for AdvertiserImpl.
+ */
+ public AdvertiserImpl() {
+ locale = SLPCore.DEFAULT_LOCALE;
+ }
+
+ /**
+ * Constructor for AdvertiserImpl.
+ *
+ * @param theLocale
+ * Locale.
+ */
+ public AdvertiserImpl(final Locale locale) {
+ this.locale = locale;
+ }
+
+ /**
+ * Get the locale of this instance.
+ *
+ * @return Locale.
+ * @see Advertiser#getLocale()
+ */
+ public Locale getLocale() {
+ return locale;
+ }
+
+ /**
+ * Set the locale of this instance.
+ *
+ * @param locale
+ * the Locale.
+ * @see Advertiser#setLocale()
+ */
+ public void setLocale(final Locale locale) {
+ this.locale = locale;
+ }
+
+ /**
+ * register a new service with the framework.
+ *
+ * @param url
+ * the ServiceURL of the service.
+ * @param attributes
+ * a Dictionary of attributes.
+ * @throws ServiceLocationException
+ * if the registration has failed for any reason.
+ * @see Advertiser#register(ServiceURL, Dictionary)
+ */
+ public void register(final ServiceURL url, final Dictionary attributes)
+ throws ServiceLocationException {
+ register(url, null, attributes);
+ }
+
+ /**
+ * register a new service with the framework using scopes.
+ *
+ * @param url
+ * the ServiceURL of the service.
+ * @param scopes
+ * a List of scopes.
+ * @param attributes
+ * a Dictionary of attributes.
+ * @throws ServiceLocationException
+ * if the registration has failed for any reason.
+ * @see Advertiser#register(ServiceURL, List, Dictionary)
+ */
+ public void register(final ServiceURL url, final List scopes,
+ final Dictionary attributes) throws ServiceLocationException {
+ ServiceRegistrationMessage reg = new ServiceRegistrationMessage();
+ reg.setServiceURL(url);
+ reg.setServiceType(url.getServiceType());
+ if (scopes != null) {
+ reg.setScopes((String[]) scopes.toArray());
+ }
+ reg.setAttrList((String[]) SLPUtils.dictToAttrList(attributes).toArray(
+ new String[] {}));
+ reg.setLocale(locale);
+ InetAddress addr;
+ try {
+ addr = InetAddress.getLocalHost();
+ } catch (UnknownHostException e) {
+ addr = SLPCore.getMyIP();
+ }
+ ServiceAcknowledgementMessage ack = (ServiceAcknowledgementMessage) SLPCore
+ .sendUnicastMessage(reg, new InetSocketAddress(addr
+ .getHostAddress(), SLPCore.SLP_PORT), true);
+
+ if (ack == null) {
+ throw new ServiceLocationException((short) 1, "Registration failed");
+ }
+ if (ack.getErrorCode() != 0) {
+ throw new ServiceLocationException((short) ack.getErrorCode(),
+ "Registration failed");
+ }
+ }
+
+ /**
+ * update an existing registration using scopes. This will replace all
+ * attributes that are already registered and add those that are not. If
+ * security is enabled, this will fail.
+ *
+ * @param url
+ * the ServiceURL of the service.
+ * @param scopes
+ * a List of scopes.
+ * @param attributes
+ * a Dictionary of attributes.
+ * @throws ServiceLocationException
+ * if the registration has failed for any reason.
+ * @see Advertiser#register(ServiceURL, List, Dictionary)
+ */
+ public void update(final ServiceURL url, final List scopes,
+ final Dictionary attributes) throws ServiceLocationException {
+ if (SLPCore.CONFIG.getSecurityEnabled()) {
+ // in a security enabled setting, updating fails as the auth blocks
+ // would be invalid.
+ throw new ServiceLocationException(
+ ServiceLocationException.AUTHENTICATION_FAILED,
+ "Cannot update an entry with auth blocks set. Need to register anew.");
+ }
+ ServiceRegistrationMessage reg = new ServiceRegistrationMessage();
+ reg.setServiceURL(url);
+ reg.setServiceType(url.getServiceType());
+ if (scopes != null) {
+ reg.setScopes((String[]) scopes.toArray());
+ }
+ reg.setAttrList((String[]) SLPUtils.dictToAttrList(attributes).toArray(
+ new String[] {}));
+ reg.setLocale(locale);
+ reg.setFresh(false);
+ InetAddress addr;
+ try {
+ addr = InetAddress.getLocalHost();
+ } catch (UnknownHostException e) {
+ addr = SLPCore.getMyIP();
+ }
+ ServiceAcknowledgementMessage ack = (ServiceAcknowledgementMessage) SLPCore
+ .sendUnicastMessage(reg, new InetSocketAddress(addr
+ .getHostAddress(), SLPCore.SLP_PORT), true);
+
+ if (ack == null) {
+ throw new ServiceLocationException((short) 1, "Registration failed");
+ }
+ if (ack.getErrorCode() != 0) {
+ throw new ServiceLocationException((short) ack.getErrorCode(),
+ "Registration failed");
+ }
+ }
+
+ /**
+ * deregister a service.
+ *
+ * @param url
+ * the ServiceURL of the service.
+ * @throws ServiceLocationException
+ * if the deregistration has failed for any reason.
+ * @see Advertiser#deregister(ServiceURL)
+ */
+ public void deregister(final ServiceURL url)
+ throws ServiceLocationException {
+ deregister(url, null);
+ }
+
+ /**
+ * deregister a service in some scopes.
+ *
+ * @param url
+ * the ServiceURL of the service.
+ * @param scopes
+ * the scopes.
+ * @throws ServiceLocationException
+ * if the deregistration has failed for any reason.
+ * @see Advertiser#deregister(ServiceURL, List)
+ * @since 0.7.1
+ */
+
+ public void deregister(final ServiceURL url, final List<String> scopes)
+ throws ServiceLocationException {
+ ServiceDeregistrationMessage dereg = new ServiceDeregistrationMessage();
+ dereg.setServiceURL(url);
+ if (scopes != null && !scopes.isEmpty()) {
+ dereg.setScopes((String[]) scopes.toArray(new String[] {}));
+ }
+ dereg.setLocale(locale);
+ InetAddress addr;
+ try {
+ addr = InetAddress.getLocalHost();
+ } catch (UnknownHostException e) {
+ addr = SLPCore.getMyIP();
+ }
+ int port = SLPCore.SLP_PORT;
+ ServiceAcknowledgementMessage ack = (ServiceAcknowledgementMessage) SLPCore
+ .sendUnicastMessage(dereg, new InetSocketAddress(addr
+ .getHostAddress(), port), true);
+ if (ack == null) {
+ throw new ServiceLocationException(
+ ServiceLocationException.INTERNAL_SYSTEM_ERROR,
+ "Deregistration failed");
+ }
+ if (ack.getErrorCode() != 0) {
+ throw new ServiceLocationException((short) ack.getErrorCode(),
+ "Deregistration failed");
+ }
+ }
+
+ /**
+ * add Attributes to a registered service. Existing attributes will be
+ * overwritten.
+ *
+ * @see Advertiser#addAttributes(ServiceURL, Dictionary)
+ * @param url
+ * the serviceURL
+ * @param attributes
+ * the attributes to add.
+ * @throws ServiceLocationException
+ *
+ */
+ public void addAttributes(final ServiceURL url, final Dictionary attributes)
+ throws ServiceLocationException {
+ update(url, null, attributes);
+ }
+
+ /**
+ * deletes attributes from a registration.
+ *
+ * @see Advertiser#deleteAttributes(ServiceURL, Dictionary)
+ * @param url
+ * the serviceURL.
+ * @param attributes
+ * the attributes to delete.
+ * @throws ServiceLocationException
+ *
+ */
+ public void deleteAttributes(final ServiceURL url,
+ final Dictionary attributes) throws ServiceLocationException {
+
+ // if security is enabled, this is not possible...
+ if (SLPCore.CONFIG.getSecurityEnabled()) {
+ throw new ServiceLocationException(
+ ServiceLocationException.AUTHENTICATION_FAILED,
+ "can not delete attributes when security is enabled");
+ }
+
+ // build the deregistration message
+ ServiceDeregistrationMessage dereg = new ServiceDeregistrationMessage();
+ dereg.setServiceURL(url);
+ dereg.setLocale(locale);
+ // set the tags!
+ Enumeration keys = attributes.keys();
+ List<String> tags = new ArrayList<String>();
+ while (keys.hasMoreElements()) {
+ tags.add(keys.nextElement().toString());
+ }
+ dereg.setTags(tags.toArray(new String[tags.size()]));
+
+ // check if tags have been set
+ if (dereg.getTags().length < 1) {
+ throw new ServiceLocationException(
+ ServiceLocationException.INTERNAL_SYSTEM_ERROR,
+ "This would lead to a complete deregistration...");
+ }
+
+ InetAddress addr;
+ try {
+ addr = InetAddress.getLocalHost();
+ } catch (UnknownHostException e) {
+ addr = SLPCore.getMyIP();
+ }
+ int port = SLPCore.SLP_PORT;
+ ServiceAcknowledgementMessage ack = (ServiceAcknowledgementMessage) SLPCore
+ .sendUnicastMessage(dereg, new InetSocketAddress(addr
+ .getHostAddress(), port), true);
+ if (ack == null) {
+ throw new ServiceLocationException(
+ ServiceLocationException.INTERNAL_SYSTEM_ERROR,
+ "Attribute deletion failed");
+ }
+ if (ack.getErrorCode() != 0) {
+ throw new ServiceLocationException((short) ack.getErrorCode(),
+ "Attribute deletion failed");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ch.ethz.iks.slp.Advertiser#shutdown()
+ */
+ public void shutdown() {
+ SLPCore.shutdownAdvertiser();
+ }
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AdvertiserImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AttributeReplyFutureImpl.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AttributeReplyFutureImpl.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AttributeReplyFutureImpl.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AttributeReplyFutureImpl.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.slp.AttributeReplyFuture;
+import org.apache.directory.slp.SLPAttribute;
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.extensions.AbstractExtension;
+import org.apache.directory.slp.extensions.UnsupportedExtension;
+import org.apache.directory.slp.messages.AbstractSLPReplyMessage;
+import org.apache.directory.slp.messages.AttributeReplyMessage;
+
+/**
+ *
+ * @author Lorenz Breu
+ */
+public class AttributeReplyFutureImpl extends NonThreadedReplyFuture implements
+ AttributeReplyFuture {
+
+
+// List of responses (i.e. message results)
+ private final List<SLPAttributeImpl> attributes = new ArrayList<SLPAttributeImpl>();
+
+ // next attribute to return when next() is called
+ private int nextAttributePosition = 0;
+
+ /**
+ * Creates a new AttributeReplyFuture with a timeout of 5x the WaitTime in SLPConfiguration
+ */
+ public AttributeReplyFutureImpl(){
+ super(SLPCore.CONFIG.getWaitTime()*5);
+ }
+
+
+ /**
+ * Creates a new AttributeReplyFuture with the specified lifetime (in ms)
+ *
+ * @param lifetime
+ * The time until the ReplyFuture is considered done in ms
+ */
+ public AttributeReplyFutureImpl(long lifetime){
+ super(lifetime);
+ }
+
+
+
+ /**
+ * Creates a new AttributeReplyFuture with the specified lifetime (in ms) expecting responses
+ * for the specified scopes.
+ *
+ * @param lifetime
+ * The lifetime in ms
+ * @param scopes
+ * The scopes for which replies are expected. used for completion checks
+ */
+ public AttributeReplyFutureImpl(long lifetime,List<String> scopes){
+ super(lifetime, scopes);
+ }
+
+ @Override
+ public void add(AbstractSLPReplyMessage reply){
+
+ if (reply==null || reply.getErrorCode()!=0){
+ return;
+ }
+ if (done){
+ // this reply is coming in too late...
+ return;
+ }
+
+ synchronized (responders){
+ if (!responders.contains(reply.getSource())) {
+ responders.add(reply.getSource());
+ } else {
+ return;
+ }
+ }
+
+ if (reply instanceof AttributeReplyMessage){
+ for (String s : reply.getResult()){
+ try{
+ String[] fields = s.split("=");
+ String at_name=fields[0];
+ if (at_name.startsWith("(")){
+ at_name=at_name.substring(1);
+ }
+ if (at_name.endsWith(")")){
+ at_name=at_name.substring(0, at_name.length()-1);
+ }
+ if (fields.length==1){
+ synchronized(attributes){
+ attributes.add(new SLPAttributeImpl(at_name));
+ }
+ } else {
+ List<String> vals = SLPUtils.stringToList(fields[1].substring(0,fields[1].length()-1), ",");
+ synchronized(attributes){
+ attributes.add(new SLPAttributeImpl(at_name,vals));
+ }
+ }
+
+
+
+ } catch (ServiceLocationException sle){
+ continue;
+ }
+ }
+ processExtensions(reply);
+
+ }
+
+
+ //stick to the basic behaviour...
+ synchronized(responses){
+ List<String> res = reply.getResultAsList();
+ if (res!=null && res.size()>0){
+ List<String> resp = reply.getResultAsList();
+ for (String s: resp){
+ if (!responses.contains(s)){
+ responses.add(s);
+ }
+ }
+ responses.notifyAll();
+ }
+ }
+
+ }
+
+ /**
+ * Process the extensions
+ *
+ * @param reply
+ * The reply message possibly containing extensions
+ *
+ */
+ private void processExtensions(AbstractSLPReplyMessage reply){
+ for (AbstractExtension ae : reply.getExtensions()){
+ if (ae instanceof UnsupportedExtension){
+ return;
+ }
+ switch (ae.getId()){
+
+
+
+ }
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see ch.ethz.iks.slp.AttributeReplyFuture#nextAttribute()
+ */
+ public SLPAttribute nextAttribute(){
+ // NOTE: a future is currently only read by one consumer (i.e. LocatorImpl) and therefor a single
+ // position marker is sufficient. Also the data containers holding responses must add new elements to the end.
+ synchronized(attributes){
+ while (!done){
+ if (attributes.size()>nextAttributePosition){
+ return attributes.get(nextAttributePosition++);
+ }
+ try{
+ attributes.wait(timeout-System.currentTimeMillis()+1000);
+ } catch (InterruptedException e){
+
+ }
+ }
+ if (attributes.size()>nextAttributePosition){
+ return attributes.get(nextAttributePosition++);
+ }
+ return null;
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see ch.ethz.iks.slp.AttributeReplyFuture#getResultAttributes()
+ */
+ public List<SLPAttribute> getResultAttributes(){
+ while (!done){
+ synchronized (donelock){
+ try {
+ donelock.wait();
+ } catch (InterruptedException ie){
+
+ }
+ }
+ }
+ return mergeAttributes();
+ }
+
+
+ /**
+ * Merges the SLPAttributes of the same type.
+ * Must be called only when the reply future is done, i.e. all responses are in.
+ *
+ * @return
+ */
+ private List<SLPAttribute> mergeAttributes(){
+
+ List<SLPAttributeImpl> t_attributes = new ArrayList<SLPAttributeImpl>(attributes);
+ List<SLPAttribute> merged = new ArrayList<SLPAttribute>();
+ List<String> keywords = new ArrayList<String>();
+ while (!t_attributes.isEmpty()){
+ SLPAttributeImpl a = t_attributes.get(0);
+ if (a.isKeyword()){
+ if (!keywords.contains(a.getName())){
+ merged.add(a);
+ keywords.add(a.getName());
+ }
+ t_attributes.remove(0);
+ } else {
+ List<SLPAttributeImpl> remove = new ArrayList<SLPAttributeImpl>();
+ for (int i=1;i<t_attributes.size();i++){
+ SLPAttributeImpl b = t_attributes.get(i);
+ if (b.getName().equals(a.getName()) && b.getType()==a.getType()){
+ a.merge(b);
+ remove.add(b);
+ }
+ }
+ merged.add(a);
+ t_attributes.remove(a);
+ for (SLPAttributeImpl j:remove){
+ t_attributes.remove(j);
+ }
+ }
+ }
+
+
+ return new ArrayList<SLPAttribute>(merged);
+
+
+
+
+ }
+
+
+
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AttributeReplyFutureImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticatedServiceURL.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticatedServiceURL.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticatedServiceURL.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticatedServiceURL.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.directory.slp.ServiceLocationException;
+
+/**
+ * Authentication support for service URLs.
+ *
+ * @author Jan S. Rellermeyer
+ */
+public class AuthenticatedServiceURL {
+
+ int lifetime = 0;
+
+ /**
+ * the authentication blocks.
+ */
+ private AuthenticationBlock[] authBlocks;
+
+ /**
+ * set the authentication blocks.
+ *
+ * @param authBlocks
+ * the authentication blocks.
+ */
+ public void setAuthBlocks(final AuthenticationBlock[] authBlocks) {
+ this.authBlocks = authBlocks;
+ }
+
+ public AuthenticationBlock[] getAuthBlocks() {
+ return authBlocks;
+ }
+
+
+
+
+ /**
+ * verify the authentication blocks.
+ *
+ * Copied over to the MINA port from the original jSLP implementation, untested
+ */
+ public void verify() throws ServiceLocationException {
+ if (authBlocks.length == 0) {
+ return;
+ }
+ for (int i = 0; i < authBlocks.length; i++) {
+ byte[] data = getAuthData(authBlocks[i].getSpi(), authBlocks[i]
+ .getTimestamp());
+ if (authBlocks[i].verify(data)) {
+ return;
+ }
+ }
+ // TODO: improve
+ throw new ServiceLocationException(
+ ServiceLocationException.AUTHENTICATION_FAILED, "");
+ }
+
+ /**
+ * get the byte representation of the authentication data.
+ *
+ * @param spi
+ * the SPI string as defined in RFC 2608
+ * @param timestamp
+ * a timestamp as defined in RFC 2608
+ * @return a byte array.
+ * @throws ServiceLocationException
+ * in case of internal errors.
+ */
+ private byte[] getAuthData(final String spi, final int timestamp)
+ throws ServiceLocationException {
+ try {
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final DataOutputStream dos = new DataOutputStream(bos);
+
+ byte[] temp = spi.getBytes();
+ dos.writeShort(temp.length);
+ dos.write(temp);
+ temp = toString().getBytes();
+ dos.writeShort(temp.length);
+ dos.write(temp);
+ dos.writeInt(timestamp);
+ return bos.toByteArray();
+ } catch (IOException ioe) {
+ throw new ServiceLocationException(
+ ServiceLocationException.INTERNAL_SYSTEM_ERROR, ioe
+ .getMessage());
+ }
+ }
+
+ /**
+ * sign the ServiceURL.
+ *
+ * @param spiList
+ * the List of SPIs
+ * @throws ServiceLocationException
+ * in case of IO errors.
+ */
+ public final void sign(final List spiList)
+ throws ServiceLocationException {
+ authBlocks = new AuthenticationBlock[spiList.size()];
+ for (int k = 0; k < spiList.size(); k++) {
+ int timestamp = SLPUtils.getTimestamp();
+ timestamp += lifetime;
+
+ String spi = (String) spiList.get(k);
+ byte[] data = getAuthData(spi, timestamp);
+ byte[] sig;
+ try {
+ sig = AuthenticationBlock.sign(spi,data);
+ } catch (Exception e) {
+ //SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
+ throw new ServiceLocationException(
+ ServiceLocationException.AUTHENTICATION_FAILED,
+ "Could not sign data");
+ }
+ authBlocks[k] = new AuthenticationBlock(timestamp,spi,sig);
+
+ }
+ }
+
+ /**
+ * sign the ServiceURL.
+ *
+ * Copied over to the MINA port from the original jSLP implementation, untested
+ *
+ * Type mismatch between the original jSLP (all Lists) and the MINA codecs (all String[])
+ * required this overload.
+ *
+ * @param spiList
+ * the String[] of SPIs
+ * @throws ServiceLocationException
+ * in case of IO errors.
+ */
+ public final void sign (final String[] spiList) throws ServiceLocationException{
+ authBlocks = new AuthenticationBlock[spiList.length];
+ for (int k = 0; k< spiList.length;k++){
+ int timestamp = SLPUtils.getTimestamp();
+ timestamp += lifetime;
+
+ String spi = (String) spiList[k];
+ byte[] data = getAuthData(spi, timestamp);
+ byte[] sig;
+ try {
+ sig = AuthenticationBlock.sign(spi,data);
+ } catch (Exception e) {
+ //SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
+ throw new ServiceLocationException(
+ ServiceLocationException.AUTHENTICATION_FAILED,
+ "Could not sign data");
+ }
+ authBlocks[k] = new AuthenticationBlock(timestamp,spi,sig);
+ }
+ }
+
+
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticatedServiceURL.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticationBlock.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticationBlock.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticationBlock.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticationBlock.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.impl;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+
+import org.apache.directory.slp.ServiceLocationException;
+
+
+/**
+ * Authentication block.
+ *
+ * @author Jan S. Rellermeyer
+ */
+public class AuthenticationBlock {
+
+ /**
+ * the BSD code for DSA.
+ */
+ public static final short BSD_DSA = 0x0002;
+
+ /**
+ * the timestamp.
+ */
+ private int timestamp;
+
+ /**
+ * the signature.
+ */
+ private byte[] sig = null;
+
+ /**
+ * the SPI.
+ */
+ private String spi = null;
+
+ public AuthenticationBlock(final int timestamp, final String spi,
+ final byte[] sig) {
+ this.timestamp = timestamp;
+ this.spi = spi;
+ this.sig = sig;
+ }
+
+ public int getTimestamp() {
+ return timestamp;
+ }
+
+ public String getSpi() {
+ return spi;
+ }
+
+
+ /**
+ * sign the AuthenticationBlock.
+ *
+ * @throws ServiceLocationException
+ * in case of processing errors.
+ */
+ public static byte[] sign(String spi,byte[] data) throws ServiceLocationException {
+ try {
+ PrivateKey privateKey = SLPCore.CONFIG.getPrivateKey(spi);
+ SLPCore.platform.logDebug("Signing with SPI: " + spi);
+ Signature signature = Signature.getInstance("SHA1withDSA");
+ signature.initSign(privateKey);
+ signature.update(data);
+ byte[] sig = signature.sign();
+ return sig;
+ } catch (Exception e) {
+ SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
+ throw new ServiceLocationException(
+ ServiceLocationException.AUTHENTICATION_FAILED,
+ "Could not sign data");
+ }
+ }
+
+
+
+
+
+ /**
+ * verify the authBlock.
+ *
+ * @param verData
+ * the auth data.
+ * @return true if verification suceeds.
+ * @throws ServiceLocationException
+ * in case of IO errors.
+ */
+ public boolean verify(final byte[] verData) throws ServiceLocationException {
+ try {
+ PublicKey publicKey = SLPCore.CONFIG.getPublicKey(spi);
+
+ Signature signature = Signature.getInstance("SHA1withDSA");
+ signature.initVerify(publicKey);
+ signature.update(verData);
+ boolean success = signature.verify(sig);
+ SLPCore.platform.logDebug((success ? "Verified with SPI: "
+ : "Verification failed with SPI: ")
+ + spi);
+
+ return success;
+ } catch (Exception e) {
+ SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
+ throw new ServiceLocationException(
+ ServiceLocationException.AUTHENTICATION_FAILED,
+ "Could not verify data with SPI: " + spi);
+ }
+ }
+
+ public byte[] getSig() {
+ return sig;
+ }
+
+ /**
+ * calculates the length of this auth block.
+ *
+ * @return the length.
+ */
+ public int getLength() {
+ return 2 // BSD
+ + 2 // Block length
+ + 4 // timestamp
+ + 2 // spi length
+ + spi.getBytes().length // spi
+ + sig.length; // signature
+ }
+
+ /**
+ * get the bytes.
+ *
+ * @return the bytes.
+ * @throws IOException
+ * in case of IO errors.
+ */
+ public void write(final DataOutputStream out) throws IOException {
+ out.writeShort(BSD_DSA); // BSD
+ out.writeShort((short) getLength());
+ out.writeInt(timestamp);
+ byte[] temp = spi.getBytes();
+ out.writeShort(temp.length);
+ out.write(temp);
+ out.write(sig);
+ }
+
+
+
+
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticationBlock.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/LocatorImpl.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/LocatorImpl.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/LocatorImpl.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/LocatorImpl.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,537 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.impl;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.directory.slp.Advertiser;
+import org.apache.directory.slp.AttributeReplyFuture;
+import org.apache.directory.slp.Locator;
+import org.apache.directory.slp.ReplyFuture;
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.ServiceReplyFuture;
+import org.apache.directory.slp.ServiceType;
+import org.apache.directory.slp.ServiceURL;
+import org.apache.directory.slp.extensions.AttributeListExtension;
+import org.apache.directory.slp.messages.AbstractSLPReplyMessage;
+import org.apache.directory.slp.messages.AbstractSLPRequestMessage;
+import org.apache.directory.slp.messages.AttributeRequestMessage;
+import org.apache.directory.slp.messages.ServiceRequestMessage;
+import org.apache.directory.slp.messages.ServiceTypeRequestMessage;
+//import com.sun.slamd.stat.CategoricalTracker;
+
+/**
+ * Implementation of the Locator interface. If the configuration does not have
+ * to provide UA functionalities, this class does not have to be included in the
+ * distribution.
+ *
+ * @author Jan S. Rellermeyer
+ */
+public final class LocatorImpl implements Locator {
+ /**
+ *
+ */
+ private Locale locale;
+
+ // If true then Service Requests include the Attribute List Extension
+ private boolean useAttributeListExtension = false;
+
+ // The thread pool for lookups
+ private static ExecutorService threadPool = Executors.newCachedThreadPool();
+
+ /**
+ * create a new LocatorImpl instance.
+ */
+ public LocatorImpl() {
+ locale = SLPCore.DEFAULT_LOCALE;
+ }
+
+ /**
+ * create a new LocatorImpl instance.
+ *
+ * @param theLocale
+ * the Locale for this instance.
+ */
+ public LocatorImpl(final Locale locale) {
+ this.locale = locale;
+ }
+
+ /**
+ * returns the locale for this instance.
+ *
+ * @return the Locale.
+ */
+ public Locale getLocale() {
+ return locale;
+ }
+
+ /**
+ * Set the locale of this instance.
+ *
+ * @param locale
+ * the Locale.
+ * @see Advertiser#setLocale()
+ */
+ public void setLocale(final Locale locale) {
+ this.locale = locale;
+ }
+
+ /**
+ * find the service types.
+ *
+ * @param namingAuthority
+ * the naming authority.
+ * @param scopes
+ * the scopes.
+ * @return a ServiceLocationEnumeration over the results.
+ * @throws ServiceLocationException
+ * if something goes wrong.
+ * @see Locator#findServiceTypes(String, List)
+ */
+ public ReplyFuture findServiceTypes(
+ final String namingAuthority, final List<String> scopes)
+ throws ServiceLocationException {
+ ServiceTypeRequestMessage srvTypeReq = new ServiceTypeRequestMessage();
+ srvTypeReq.setNamingAuthority(namingAuthority);
+ if (scopes!=null){
+ if (scopes.size()>0){
+ srvTypeReq.setScopes(SLPUtils.listToStringArray(scopes));
+ }
+ }
+ srvTypeReq.setLocale(locale);
+ return sendRequest(srvTypeReq,scopes);
+ }
+
+
+
+ /**
+ * find services.
+ *
+ * @param type
+ * the service type.
+ * @param scopes
+ * the scopes.
+ * @param searchFilter
+ * an LDAP filter expression.
+ * @return a ServiceLocationEnumeration over the results.
+ * @throws ServiceLocationException
+ * if something goes wrong.
+ * @see Locator#findAttributes(ServiceType, List, List)
+ */
+ public ServiceReplyFuture findServices(final ServiceType type,
+ final List<String> scopes, final String searchFilter)
+ throws ServiceLocationException {
+ try {
+ ServiceRequestMessage srvReq = new ServiceRequestMessage();
+ srvReq.setServiceType(type);
+ if (scopes!=null){
+ if (scopes.size()>0){
+ srvReq.setScopes(SLPUtils.listToStringArray(scopes));
+ }
+ }
+ srvReq.setPredicate(searchFilter);
+ srvReq.setLocale(locale);
+
+ if (useAttributeListExtension){
+ srvReq.addExtension(new AttributeListExtension("",""));
+ }
+
+ if (SLPCore.CONFIG.getSecurityEnabled()){
+ srvReq.setSPIs(SLPUtils.stringToStringArray(SLPCore.CONFIG.getSPI(), ","));
+ }
+
+ return (ServiceReplyFutureImpl) sendRequest(srvReq,scopes);
+ } catch (IllegalArgumentException ise) {
+
+ throw new ServiceLocationException(
+ ServiceLocationException.INTERNAL_SYSTEM_ERROR, ise
+ .getMessage()
+ + ": " + searchFilter);
+ }
+ }
+
+
+ /**
+ * find attributes by service URL.
+ *
+ * @param url
+ * the ServiceURL of the service.
+ * @param scopes
+ * a List of scoped to be included.
+ * @param attributeIds
+ * a List of attributes for which the values should be returned,
+ * if they exist.
+ * @return ServiceLocationEnumeration over the results.
+ * @throws ServiceLocationException
+ * in case of network errors etc.
+ * @see Locator#findAttributes(ServiceURL, List, List)
+ */
+ public AttributeReplyFuture findAttributes(final ServiceURL url,
+ final List scopes, final List attributeIds)
+ throws ServiceLocationException {
+ AttributeRequestMessage attrReq = new AttributeRequestMessage();
+ attrReq.setServiceURL(url);
+ if (scopes!=null){
+ if (scopes.size()>0){
+ attrReq.setScopes(SLPUtils.listToStringArray(scopes));
+ }
+ }
+ attrReq.setLocale(locale);
+ attrReq.setTags(SLPUtils.listToStringArray(attributeIds));
+ return findAttributes(attrReq);
+ }
+
+ /**
+ * find attributes by service type.
+ *
+ * @param type
+ * the service type.
+ * @param scopes
+ * the scopes.
+ * @param attributeIds
+ * a List of attributes for which the values should be returned,
+ * if they exist.
+ * @return a ServiceLocationEnumeration over the results.
+ * @throws ServiceLocationException
+ * if something goes wrong.
+ * @see Locator#findAttributes(ServiceType, List, List)
+ */
+ public AttributeReplyFuture findAttributes(final ServiceType type,
+ final List scopes, final List attributeIds)
+ throws ServiceLocationException {
+ AttributeRequestMessage attrReq = new AttributeRequestMessage();
+ attrReq.setServiceURL(new ServiceURL(type,ServiceURL.LIFETIME_DEFAULT));
+ if (scopes!=null){
+ if (scopes.size()>0){
+ attrReq.setScopes(SLPUtils.listToStringArray(scopes));
+ }
+ }
+ attrReq.setLocale(locale);
+ attrReq.setTags(SLPUtils.listToStringArray(attributeIds));
+ return findAttributes(attrReq);
+ }
+
+
+ /* (non-Javadoc)
+ * @see ch.ethz.iks.slp.Locator#listenOnSLPPort()
+ */
+ public void listenOnSLPPort() throws ServiceLocationException {
+ SLPCore.initializeListeners();
+ }
+
+
+
+ /**
+ * common method that handles a predefined AttributeRequest.
+ *
+ * @param attReq
+ * the AttributeRequest.
+ * @return the resulting Attributes as String.
+ * @throws ServiceLocationException
+ * in case of network errors.
+ */
+ private AttributeReplyFuture findAttributes(
+ final AttributeRequestMessage attReq) throws ServiceLocationException {
+ return (AttributeReplyFuture) sendRequest(attReq,SLPUtils.arrayToList(attReq.getScopes()));
+ }
+
+
+// public void shutdown(){
+// SLPCore.shutdownUserAgent();
+// }
+
+
+
+
+
+ /**
+ * send a request. Uses direct communication to a DA or multicast
+ * convergence, if no DA is known for the specific scope. mcc is ignored when sufficient results are in
+ *
+ * @param req
+ * the request.
+ * @param scopeList
+ * the scopes.
+ * @param numberOfResults
+ * returns when this number of results have been acquired or the mcc ends
+ * @return the list of results.
+ * @throws ServiceLocationException
+ * if something goes wrong.
+ */
+ private ReplyFuture sendRequest(final AbstractSLPRequestMessage req, final List<String> scopeList)
+ throws ServiceLocationException {
+ List<String> scopes = scopeList != null ? scopeList : SLPUtils.stringToList(SLPCore.CONFIG.getScopes(),",");
+ NonThreadedReplyFuture reply;
+ if (req instanceof ServiceRequestMessage){
+ reply = new ServiceReplyFutureImpl(10000, scopes);
+ } else if (req instanceof AttributeRequestMessage){
+ reply = new AttributeReplyFutureImpl(10000, scopes);
+ } else {
+ reply = new NonThreadedReplyFuture(10000, scopes);
+ }
+
+ threadPool.execute(new AsynchRequestThread(reply,req,scopes));
+
+ return reply;
+ }
+
+ /**
+ * send a request to a DA.
+ *
+ * @param req
+ * the request.
+ * @param dAaddresses
+ * the DA address.
+ * @return the <code>List</code> of results.
+ * @throws ServiceLocationException
+ */
+ private static void sendRequestToDA(final ReplyFuture replyfuture, final AbstractSLPRequestMessage req,
+ final List<String> dAaddresses, final String[] scopes) {
+
+ threadPool.execute(new AsynchDAThread(replyfuture,req,dAaddresses, scopes));
+ }
+
+
+ /**
+ * Thread responsible for sending a request to one or more DAs
+ *
+ * @author breul
+ *
+ */
+ private static class AsynchDAThread implements Runnable {
+
+
+ // The reply future to be filled in
+ private final ReplyFuture replyfuture;
+
+ // The message to be sent
+ private final AbstractSLPRequestMessage msg;
+
+ // The DAs to be contacted
+ private final List<String> dAs;
+
+ // The scope this request is covering
+ private final String[] scopes;
+
+ /**
+ * The constructor to kick off requests to DAs
+ *
+ * @param rf
+ * The reply future to be filled in
+ * @param req
+ * The message to be sent (a request)
+ * @param dAaddresses
+ * The List of DA addresses to be contacted
+ */
+ public AsynchDAThread(ReplyFuture rf, AbstractSLPRequestMessage req, List<String> dAaddresses, String[] scopes){
+ replyfuture=rf;
+ msg=req;
+ dAs=dAaddresses;
+ this.scopes=scopes;
+
+ }
+
+
+ public void run() {
+ while (dAs.size()>0) {
+ int index = 0;
+ try {
+ // often there will be only one...
+ if (dAs.size()>1){
+ index = (int) Math.rint(Math.random()*(dAs.size()-1));
+ }
+ // set the receiver address
+ InetAddress address = InetAddress.getByName((String) dAs
+ .get(index));
+ int port = SLPCore.SLP_PORT;
+ AbstractSLPReplyMessage reply = SLPCore.sendReliableUnicastMessage(msg,new InetSocketAddress(address,port) ,true);
+ if (reply == null){
+ // remove DA from list.
+ final Object url = dAs.get(index);
+ SLPUtils.removeValueFromAll(SLPCore.dAs, url);
+ SLPCore.dASPIs.remove(url);
+ dAs.remove(index);
+ // Try the next DA in the list.
+ continue;
+ }
+ // add the reply to the future and mark the scope used as "handled"
+ replyfuture.add(reply);
+ break;
+
+ } catch (Exception e) {
+ SLPCore.platform.logError(e.getMessage(), e
+ .fillInStackTrace());
+ // something went wrong.
+ // remove DA from list.
+ final Object url = dAs.get(index);
+ SLPUtils.removeValueFromAll(SLPCore.dAs, url);
+ SLPCore.dASPIs.remove(url);
+ dAs.remove(index);
+ // Try the next DA in the list.
+ continue;
+ }
+ }
+ // mark the reply future as done unless there are still other scopes to be handled.
+ replyfuture.setDone(scopes,false);
+ }
+}
+
+
+
+
+ /**
+ * The thread used to send requests, either to pass them on to DAs or two kick off a multicast convergence
+ *
+ * @author breul
+ *
+ */
+ private static class AsynchRequestThread implements Runnable{
+
+ // The reply future to be filled in
+ private final ReplyFuture replyfuture;
+
+ // The message to be sent (a request)
+ private final AbstractSLPRequestMessage msg;
+
+ // The scopes to handle
+ private final List<String> scopes;
+
+
+
+ /**
+ * The constructor to start the request
+ *
+ * @param rf
+ * The reply future to fill in
+ * @param req
+ * The request to send
+ * @param scopelist
+ * The list of scopes to be handled
+ */
+ public AsynchRequestThread(ReplyFuture rf, AbstractSLPRequestMessage req, List<String> scopelist){
+ replyfuture=rf;
+ msg=req;
+ scopes=scopelist;
+ }
+
+ public void run(){
+ // if a UA is in multiple scopes, and a DA is also in these multiple scopes, then the UA
+ // would send the same request to such DA for each scope. Therefor we keep track
+ // of DAs that have been contacted.
+ List<String> usedDAs = new ArrayList<String>();
+ boolean scopeOverlap = false;
+
+ for (String scope:scopes) {
+ scope = scope.toLowerCase();
+ List<String> dAs = SLPCore.dAs.get(scope);
+
+ SLPCore.platform
+ .logDebug("DAS FOR SCOPE " + scope + ": " + dAs);
+
+ // no DA for the scope known ?
+ // try to find one
+ if ((dAs == null || dAs.isEmpty()) && !SLPCore.noDiscovery) {
+ try {
+ SLPCore.daLookup(new String[] { scope });
+ } catch (ServiceLocationException sle){
+
+ }
+
+ // wait a short time for incoming replies
+ synchronized (SLPCore.dAs) {
+ try {
+ SLPCore.dAs.wait(SLPCore.CONFIG.getWaitTime() / 4);
+ } catch (InterruptedException e) {
+ SLPCore.platform.logError(e.getMessage(), e);
+ // Restore the interrupted status as we're not the owner of the current thread
+ Thread.currentThread().interrupt();
+ }
+ }
+ dAs = SLPCore.dAs.get(scope);
+
+ }
+ List<String> newDas = new ArrayList<String>();
+ // remove those already contacted while handling a previous scope...
+ if (dAs!=null){
+ for (String s: dAs){
+ if (usedDAs.contains(s)){
+ scopeOverlap = true;
+ } else {
+ newDas.add(s);
+ }
+ }
+ }
+
+ if (newDas != null && !newDas.isEmpty()) {
+ // a DA is known for this scope which has not already been asked in a different scope, so contact it
+ sendRequestToDA(replyfuture,msg,newDas, new String[]{scope});
+ // add DA to set of used DAs
+ usedDAs.addAll(newDas);
+ // reset overlap flag
+ scopeOverlap = false;
+ } else if (scopeOverlap){
+ // No new DA around for this scope, as the scope was covered by a previous request
+ replyfuture.setDone(new String[]{scope}, false);
+ } else {
+ // still no DA available and no overlap of scopes and DAs, use multicast
+ try {
+ // TODO: clarify scope handling in MCC
+ // two possibilities:
+ // a: include all scopes in mcc, leading to repeat responses from SAs and DAs in more than one scope, but we can break after only 1 MCC
+ // b: send to only a specific scope, possibly leading to multiple rounds of MCC
+ // c: add known responders to the initial mcc request to minimize traffic (as done now).
+ msg.setPrevResponders(replyfuture.getResponders());
+ SLPCore.multicastConvergence(replyfuture,msg);
+ } catch (ServiceLocationException sle){
+
+ continue;
+ }
+
+ }
+ }
+
+ }
+
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see ch.ethz.iks.slp.Locator#isUseAttributeListExtension()
+ */
+ public boolean isUseAttributeListExtension() {
+ return useAttributeListExtension;
+ }
+
+ /* (non-Javadoc)
+ * @see ch.ethz.iks.slp.Locator#setUseAttributeListExtension(boolean)
+ */
+ public void setUseAttributeListExtension(boolean useAttributeListExtension) {
+ this.useAttributeListExtension = useAttributeListExtension;
+ }
+
+
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/LocatorImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/NonThreadedReplyFuture.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/NonThreadedReplyFuture.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/NonThreadedReplyFuture.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/NonThreadedReplyFuture.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,284 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.slp.ReplyFuture;
+import org.apache.directory.slp.messages.AbstractSLPReplyMessage;
+
+/**
+ * The future returned when performing SLP lookups. It can be accessed while results still come in using next(),
+ * or after all results have arrived using getResult().
+ *
+ * @author Lorenz Breu
+ */
+public class NonThreadedReplyFuture implements ReplyFuture{
+
+ // used to wait for done status
+ protected final Object donelock = new Object();
+
+ //List of responses (i.e. message results)
+ protected final List<String> responses = new ArrayList<String>();
+
+ // List of responders, used to build initial list of previous responders for multicast convergence
+ protected final List<String> responders = new ArrayList<String>();
+
+ // point when reply future is closed automatically
+ protected long timeout;
+
+ // set to true when all operations producing results have completed
+ protected boolean done = false;
+
+ // the next position to be returned using the next() method.
+ // currently a future object is read by only one consumer.
+ private int nextPosition = 0;
+
+ // the list of scopes this future has to cover, used to control correct closure.
+ private List<String> unhandledScopes = new ArrayList<String>();
+
+
+
+ /**
+ * Basic constructor, sets a default timeout value and uses all scopes definied in CONFIG
+ */
+ public NonThreadedReplyFuture(){
+ //TODO: which wait time should we use here? has to be larger than the time it takes to start and end the multicast convergence
+ this(SLPCore.CONFIG.getWaitTime()*5);
+ }
+
+
+
+
+ /**
+ * Constructor with a specific lifetime. The future expects to handle all scopes defined in CONFIG
+ *
+ * @param lifetime
+ * Number of milliseconds this future should remain open to receive results.
+ */
+ public NonThreadedReplyFuture(long lifetime){
+ unhandledScopes = SLPUtils.stringToList(SLPCore.CONFIG.getScopes().toLowerCase(), ",");
+ timeout = System.currentTimeMillis()+lifetime;
+
+ }
+
+
+ /**
+ * Detailed constructor.
+ *
+ * @param lifetime
+ * Number of milliseconds this future should remain open to receive results.
+ * @param scopes
+ * List of scopes to be handled.
+ */
+ public NonThreadedReplyFuture(long lifetime,List<String> scopes){
+ for (String s : scopes){
+ unhandledScopes.add(s.toLowerCase());
+ }
+ timeout = System.currentTimeMillis()+lifetime;
+
+ }
+
+
+
+ /**
+ * Adds the result of an SLP reply message to the list of responses and the sender of the
+ * reply to the list of responders, if the error code is 0.
+ *
+ * @param reply
+ * An AbstractSLPReplyMessage obtained through unicast or multicast
+ */
+ public void add(AbstractSLPReplyMessage reply){
+
+ if (System.currentTimeMillis()>=timeout){
+ setDone(new String[]{}, true);
+ return;
+ }
+
+ if (reply==null || reply.getErrorCode()!=0){
+ return;
+ }
+ if (done){
+ // this reply is coming in too late...
+ return;
+ }
+
+ synchronized (responders){
+ if (!responders.contains(reply.getSource())) {
+ responders.add(reply.getSource());
+ } else {
+ return;
+ }
+ }
+
+ synchronized(responses){
+ List<String> res = reply.getResultAsList();
+ if (res!=null && res.size()>0){
+ List<String> resp = reply.getResultAsList();
+ for (String s: resp){
+ if (!responses.contains(s)){
+ responses.add(s);
+ }
+ }
+ responses.notifyAll();
+ }
+ }
+
+ }
+
+ /**
+ * Close the future.
+ * If the override flag is set, the future will be closed directly.
+ * If override is false, then the defined scopes will be removed from the list of unhandled scopes
+ * and the future will be closed only if no scopes remain unhandled. Else it will remain open.
+ *
+ * @param scopes
+ * The scopes to mark as done.
+ * @param override
+ * Set to true if the future should be closed even if scopes remain unhandled (e.g. timeout)
+ */
+ public synchronized void setDone(String[] scopes, boolean override){
+ synchronized (unhandledScopes){
+ for (String s: scopes){
+ unhandledScopes.remove(s);
+ }
+ }
+
+ if (!unhandledScopes.isEmpty() && !override){
+ //oops, not all scopes that were expected to be handled actually were handled, so keep waiting
+ return;
+ }
+ if (!done){
+ done=true;
+ synchronized(donelock){
+ donelock.notifyAll();
+ }
+ synchronized(responses){
+ responses.notifyAll();
+ }
+
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see ch.ethz.iks.slp.ServiceLocationEnumeration#next()
+ */
+ public String next(){
+ // NOTE: a future is currently only read by one consumer (i.e. LocatorImpl) and therefor a single
+ // position marker is sufficient. Also the data containers holding responses must add new elements to the end.
+ synchronized(responses){
+ while (!done){
+ long remaining = timeout - System.currentTimeMillis();
+ if (remaining>0){
+ if (responses.size()>nextPosition){
+ return responses.get(nextPosition++);
+ }
+ try{
+ responses.wait(remaining);
+ } catch (InterruptedException e){
+ continue;
+ }
+ } else {
+ setDone(new String[]{}, true);
+ break;
+ }
+ }
+ if (responses.size()>nextPosition){
+ return responses.get(nextPosition++);
+ }
+ return null;
+ }
+ }
+
+
+ /**
+ * Returns the status of the future.
+ *
+ * @return
+ * True if done, false if results can still be added.
+ */
+ public synchronized boolean isDone(){
+ return done;
+ }
+
+
+ /**
+ * Blocking call that waits until the future is marked as "done" before returning all available responses.
+ *
+ * @return
+ * A list of all results obtained during the unicast or multicast SLP operation in the form of Strings.
+ */
+ public List<String> getResult(){
+ while (!done){
+ synchronized (donelock){
+ try {
+ long remaining = timeout - System.currentTimeMillis();
+ if (remaining>0){
+ donelock.wait(remaining);
+ } else {
+ setDone(new String[]{}, true);
+ break;
+ }
+ } catch (InterruptedException ie){
+ continue;
+ }
+ }
+ }
+ return responses;
+ }
+
+
+ /**
+ * Returns the sources of all reply messages with error code 0 passed on to this future.
+ *
+ * @return
+ * Array of IP addresses as Strings in dot notation of the sources of reply messages.
+ */
+ public synchronized String[] getResponders(){
+ return SLPUtils.listToStringArray(responders);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Enumeration#hasMoreElements()
+ */
+ public synchronized boolean hasMoreElements() {
+ return (responses.size()>nextPosition);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Enumeration#nextElement()
+ */
+ public String nextElement() {
+ return next();
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/NonThreadedReplyFuture.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/OSGiPlatformAbstraction.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/OSGiPlatformAbstraction.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/OSGiPlatformAbstraction.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/OSGiPlatformAbstraction.java Tue Jun 9 12:00:29 2009
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.directory.slp.impl;
+
+import java.util.Dictionary;
+
+import org.apache.directory.slp.impl.filter.Filter;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+/**
+ * Platform abstraction for the OSGi implementation.
+ *
+ * @author Jan S. Rellermeyer
+ */
+public class OSGiPlatformAbstraction implements PlatformAbstraction,
+ ServiceListener {
+
+ /**
+ *
+ */
+ private final BundleContext context;
+
+ /**
+ *
+ */
+ private LogService log = new NullPatternLogService();
+
+ /**
+ * Constructor.
+ *
+ * @param context
+ * the bundle context from the OSGi framework.
+ * @param log
+ * the LogService, or null.
+ * @param debug
+ * true if debugging is enabled.
+ * @throws InvalidSyntaxException
+ * may never happen
+ */
+ OSGiPlatformAbstraction(BundleContext context) throws InvalidSyntaxException {
+ this.context = context;
+
+ // initially get the LogService
+ final ServiceReference sref = context
+ .getServiceReference(LogService.class.getName());
+ if (sref != null) {
+ this.log = (LogService) context.getService(sref);
+ }
+
+ // track the LogService for life cycle events
+ context.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + LogService.class.getName() + ")");
+
+ logDebug("jSLP OSGi started.");
+ }
+
+ /**
+ *
+ * @see org.apache.directory.slp.impl.PlatformAbstraction#createFilter(java.lang.String)
+ */
+ public Filter createFilter(String filterString) {
+ try {
+ final org.osgi.framework.Filter filter = context
+ .createFilter(filterString);
+ return new Filter() {
+ public boolean match(Dictionary values) {
+ return filter.match(values);
+ }
+
+ public String toString() {
+ return filter.toString();
+ }
+ };
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ }
+
+ /**
+ *
+ * @see org.apache.directory.slp.impl.PlatformAbstraction#logDebug(java.lang.String)
+ */
+ public void logDebug(String message) {
+ if(SLPCore.CONFIG.getDebugEnabled()) {
+ log.log(LogService.LOG_DEBUG, message);
+ }
+ }
+
+ /**
+ *
+ * @see org.apache.directory.slp.impl.PlatformAbstraction#logDebug(java.lang.String,
+ * java.lang.Throwable)
+ */
+ public void logDebug(String message, Throwable exception) {
+ if(SLPCore.CONFIG.getDebugEnabled()) {
+ log.log(LogService.LOG_DEBUG, message, exception);
+ }
+ }
+
+ /**
+ *
+ * @see org.apache.directory.slp.impl.PlatformAbstraction#logError(java.lang.String)
+ */
+ public void logError(String message) {
+ log.log(LogService.LOG_ERROR, message);
+ }
+
+ /**
+ *
+ * @see org.apache.directory.slp.impl.PlatformAbstraction#logError(java.lang.String,
+ * java.lang.Throwable)
+ */
+ public void logError(String message, Throwable exception) {
+ log.log(LogService.LOG_ERROR, message, exception);
+ }
+
+ /**
+ *
+ * @see org.apache.directory.slp.impl.PlatformAbstraction#logTraceMessage(java.lang.String)
+ */
+ public void logTraceMessage(String message) {
+ if(SLPCore.CONFIG.getTraceMessage()) {
+ log.log(LogService.LOG_INFO, message);
+ }
+ }
+
+ /**
+ *
+ * @see org.apache.directory.slp.impl.PlatformAbstraction#logTraceDrop(java.lang.String)
+ */
+ public void logTraceDrop(String message) {
+ if(SLPCore.CONFIG.getTraceDrop()) {
+ log.log(LogService.LOG_INFO, message);
+ }
+ }
+
+ /**
+ *
+ * @see org.apache.directory.slp.impl.PlatformAbstraction#logTraceMessage(java.lang.String)
+ */
+ public void logTraceReg(String message) {
+ if(SLPCore.CONFIG.getTraceReg()) {
+ log.log(LogService.LOG_INFO, message);
+ }
+ }
+
+ /**
+ *
+ * @see org.apache.directory.slp.impl.PlatformAbstraction#logWarning(java.lang.String)
+ */
+ public void logWarning(String message) {
+ log.log(LogService.LOG_WARNING, message);
+ }
+
+ /**
+ *
+ * @see org.apache.directory.slp.impl.PlatformAbstraction#logWarning(java.lang.String,
+ * java.lang.Throwable)
+ */
+ public void logWarning(String message, Throwable exception) {
+ log.log(LogService.LOG_WARNING, message, exception);
+ }
+
+ /**
+ *
+ * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+ */
+ public void serviceChanged(final ServiceEvent event) {
+ switch (event.getType()) {
+ case ServiceEvent.REGISTERED:
+ log = (LogService) context.getService(event.getServiceReference());
+ return;
+ case ServiceEvent.UNREGISTERING:
+ log = new NullPatternLogService();
+ default:
+ }
+ }
+
+ // if no LogService is present, we use a dummy log
+ private class NullPatternLogService implements LogService {
+
+ public void log(int level, String message) {
+ if(level == LogService.LOG_ERROR || level == LogService.LOG_WARNING) {
+ System.err.println(message);
+ } else {
+ System.out.println(message);
+ }
+ }
+
+ public void log(int level, String message, Throwable exception) {
+ log(level, message + exception.getMessage());
+ }
+
+ public void log(ServiceReference sr, int level, String message) {
+ log(null, level, message);
+ }
+
+ public void log(ServiceReference sr, int level, String message, Throwable t) {
+ log(null, level, message, t);
+ }
+ }
+}
Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/OSGiPlatformAbstraction.java
------------------------------------------------------------------------------
svn:mime-type = text/plain